SvelteKit
Uma página SvelteKit pré-renderizada cujo formulário envia direto para o Ikiform, aprimorada com fetch quando o JavaScript carrega. Funciona com adapter-static.
Esta página não precisa de servidor: o action do formulário é o seu endpoint do Ikiform, então funciona com adapter-static e em qualquer host estático. Sem JavaScript, ela envia e redireciona como HTML puro; com JavaScript, envia com fetch e mostra o resultado no lugar. Para enviar por uma form action com uma chave secreta, veja Svelte.
Por que não usar use:enhance
O use:enhance do SvelteKit só funciona com formulários method="POST" que apontam para actions definidas em um arquivo +page.server.js. O Ikiform é uma URL externa, então a página usa um pequeno handler onsubmit. O progressive enhancement é o mesmo: o formulário funciona primeiro, e o script o melhora.
Configuração
Adicione variáveis de ambiente públicas
.env PUBLIC_IKIFORM_FORM_ID=frm_xxxxxxxxxxxxxxxx PUBLIC_SITE_URL=https://example.comPUBLIC_SITE_URLserve para o redirecionamento sem JavaScript. Durante a pré-renderização,page.url.originéhttp://sveltekit-prerender, não o seu domínio, então o redirecionamento não pode ser montado a partir dele.Pré-renderize a página
src/routes/contact/+page.js export const prerender = true;Adicione o formulário
src/routes/contact/+page.svelte <script> import { PUBLIC_IKIFORM_FORM_ID, PUBLIC_SITE_URL } from "$env/static/public"; const endpoint = `https://ikiform.com/f/${PUBLIC_IKIFORM_FORM_ID}`; let status = $state("idle"); let errors = $state({}); let message = $state(""); async function onsubmit(event) { event.preventDefault(); status = "sending"; try { const response = await fetch(endpoint, { method: "POST", headers: { Accept: "application/json" }, body: new FormData(event.currentTarget), }); const result = await response.json(); if (result.ok) { status = "sent"; return; } errors = result.error.fields ?? {}; message = result.error.message; } catch { message = "Couldn't reach the server. Try again."; } status = "error"; } </script> {#if status === "sent"} <p>Thanks, we got it.</p> {:else} <form action={endpoint} method="POST" {onsubmit}> <label> Email <input name="email" type="email" autocomplete="email" required aria-invalid={errors.email ? "true" : undefined} /> </label> {#if errors.email}<p>{errors.email[0]}</p>{/if} <label> Message <textarea name="message" rows="5"></textarea> </label> <input type="hidden" name="_redirect" value={`${PUBLIC_SITE_URL}/contact/thanks`} /> <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden /> {#if status === "error" && !errors.email}<p role="alert">{message}</p>{/if} <button disabled={status === "sending"}>{status === "sending" ? "Sending" : "Send"}</button> </form> {/if}Adicione um
src/routes/contact/thanks/+page.sveltecomo destino do redirecionamento.
Se você usa a CSP do SvelteKit
Com kit.csp configurado, permita o Ikiform tanto para o envio com fetch quanto para o envio do formulário comum. Caso contrário, o navegador bloqueia um ou outro.
const config = {
kit: {
csp: {
directives: {
"connect-src": ["self", "https://ikiform.com"],
"form-action": ["self", "https://ikiform.com"],
},
},
},
};
export default config;Domínios permitidos
Liste a produção mais os seus hosts de preview.
| Onde o formulário roda | Adicione em Allowed domains |
|---|---|
vite dev | localhost. Ele corresponde a http://localhost:5173: o Ikiform compara só o nome do host, nunca a porta. |
| Seu domínio | example.com, que também cobre www.example.com |
| Vercel | your-project.vercel.app. URLs de preview como your-project-git-branch-team.vercel.app não correspondem a ele; adicione o host exato do preview enquanto testa um. |
| Cloudflare Pages | your-project.pages.dev. URLs de preview como abc123.your-project.pages.dev são subdomínios dele, então já correspondem. |
| Netlify | your-site.netlify.app. Deploy previews (deploy-preview-12--your-site.netlify.app) e branch deploys (branch--your-site.netlify.app) não são subdomínios dele, então adicione o host exato do preview enquanto testa um. |
- Nunca adicione
vercel.app,pages.devounetlify.appsozinhos. Todo site naquele host corresponderia, inclusive os de outras pessoas.
Checklist de teste
- Rode o servidor de desenvolvimento com
localhostnos domínios permitidos e envie. A mensagem de agradecimento deve substituir o formulário. - Rode
vite builde confira se o resultado contémcontact.htmlcom o formulário já dentro. - Desative o JavaScript, recarregue e envie. No seu domínio
https:, você deve chegar a/contact/thanks. - Envie a partir de um deploy de preview e confirme que ele não é marcado como spam.
Solução de problemas
| O que você vê | Por quê | Correção |
|---|---|---|
O build falha dizendo que PUBLIC_IKIFORM_FORM_ID não é exportado por $env/static/public | A variável não está definida onde o build roda | Adicione em .env localmente e nas configurações de build do seu host. |
Nada acontece ao enviar, e o console mostra um erro de CORS sobre o header x-sveltekit-action | use:enhance em um formulário que envia para fora do seu app | Remova-o e mantenha o handler onsubmit. |
O navegador se recusa a enviar o formulário por causa de form-action ou connect-src | kit.csp não inclui o Ikiform | Adicione https://ikiform.com às duas diretivas. |
| Sem JavaScript, você cai na página de agradecimento do Ikiform | PUBLIC_SITE_URL é http:, ou o domínio não está nos domínios permitidos | Use o seu endereço https: e adicione o domínio. |
Os envios chegam no filtro de spam com origin_mismatch | A página que enviou não está nos domínios permitidos do formulário | Adicione o host da tabela acima. Com Reject escolhido, os mesmos envios recebem 403 origin_not_allowed. |