Розробка форми з передзаповненням даних (через URL/API) на сайті
Передзаповнені форми підвищують конверсію та зменшують тертя. Користувач, який перейшов за посиланням з електронної пошти або CRM, бачить вже заповнені поля — йому залишається лише перевірити та відправити. Форма з передзаповненням з API економить час при повторних зверненнях.
Джерела передзаповнення
URL-параметри — найпростіший варіант. Посилання виду /apply?name=Іван&[email protected]&plan=pro заповнює відповідні поля при завантаженні сторінки.
JWT-токен в URL — дані зашифровані, не редагуються користувачем безпосередньо, можна передавати чутливі значення.
API-запит — форма завантажує дані користувача за його токеном авторизації або за ID сутності (замовлення, заявка, профіль).
SessionStorage / Cookie — дані з попередньої сесії або з іншої сторінки того ж сайту.
Передзаповнення з URL-параметрів
function prefillFromURL() {
const params = new URLSearchParams(window.location.search);
// Білий список — ніколи не заповнювати приховані/системні поля з URL
const allowed = ['name', 'email', 'phone', 'company', 'plan', 'promo'];
for (const field of allowed) {
const value = params.get(field);
if (!value) continue;
const el = document.querySelector(`[name="${field}"]`);
if (!el) continue;
// Санітизація — тільки текст, без HTML
el.value = DOMPurify.sanitize(value, { ALLOWED_TAGS: [] });
el.dispatchEvent(new Event('input', { bubbles: true }));
}
}
document.addEventListener('DOMContentLoaded', prefillFromURL);
Передзаповнення через JWT
Безпечніше, ніж відкриті параметри — дані підписані, неможливо підмінити без знання таємниці:
// Посилання виду: /form?token=eyJhbGci...
async function prefillFromToken() {
const token = new URLSearchParams(window.location.search).get('token');
if (!token) return;
const res = await fetch('/api/form-prefill', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token }),
});
if (!res.ok) return;
const data = await res.json();
applyFormData(data);
}
На сервері Laravel:
public function decodePrefillToken(Request $request)
{
try {
$payload = JWT::decode($request->token, new Key(config('app.key'), 'HS256'));
return response()->json((array) $payload->form_data);
} catch (\Exception $e) {
return response()->json(['error' => 'Invalid token'], 422);
}
}
Генерація токена (наприклад, при відправленні електронної пошти):
$payload = [
'form_data' => [
'name' => $user->name,
'email' => $user->email,
'plan' => 'pro',
],
'exp' => now()->addHours(24)->timestamp,
];
$token = JWT::encode($payload, config('app.key'), 'HS256');
$link = route('form') . '?token=' . $token;
Передзаповнення з API (для авторизованих користувачів)
async function prefillFromProfile() {
const res = await fetch('/api/user/profile');
if (!res.ok) return;
const profile = await res.json();
const mapping = {
'contact[name]': profile.full_name,
'contact[email]': profile.email,
'contact[phone]': profile.phone,
'address[city]': profile.city,
'address[street]': profile.address,
};
for (const [fieldName, value] of Object.entries(mapping)) {
if (value == null) continue;
const el = document.querySelector(`[name="${fieldName}"]`);
if (el) el.value = value;
}
}
React Hook Form + передзаповнення
function ApplicationForm({ userId }) {
const { register, reset, handleSubmit } = useForm();
useEffect(() => {
async function load() {
const res = await fetch(`/api/users/${userId}/prefill`);
const data = await res.json();
reset(data); // заповнює всі поля форми
}
if (userId) load();
}, [userId, reset]);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('name')} placeholder="Ім'я" />
<input {...register('email')} placeholder="Email" />
{/* ... */}
</form>
);
}
Безпека
-
Ніколи не передзаповнювати з URL поля типу
role,is_admin,price,discount - Всі значення з URL санітизувати перед вставленням (XSS через
value) - Дані з токена перевіряти на сервері — не довіряти фронтенду
- Використовувати
rel="noopener noreferrer"при генерації посилань у зовнішніх системах
Візуальна індикація
Передзаповнені поля варто візуально виділити, щоб користувач зрозумів, що дані вже вставлені, і міг їх перевірити:
.field--prefilled {
background: #f0f9ff;
border-color: #38bdf8;
}
.field--prefilled::after {
content: '✓ передзаповнено';
font-size: 0.75rem;
color: #0369a1;
}
Терміни
Передзаповнення з URL із санітизацією — 1 робочий день. JWT-токени + серверний API з маппінгом полів та індикацією — 3–4 дні.







