Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add Superforms example for Svelte 5 #42

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

AyushSehrawat
Copy link

@AyushSehrawat AyushSehrawat commented Dec 27, 2024

This PR adds superforms example to the README.md using superforms onUpdated event to reset the widget and svelte-turnstile callback to set token

events C0HjOx0t

Comment on lines +192 to +194
on:callback={(event) => {
$formData['cf-turnstile-response'] = event.detail.token;
}}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my experience manually adding the token with the callback event wasn't necessary. Did you find that there was an edge case here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was not being added automatically so had to this. I can check it again to confirm!

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be great! I have superforms + turnstile on a large site and it's working great without this, but I'm not sure if anything changed (it's on an older version of SvelteKit & Svelte 4)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried without and it isn't working

Below is some part of the code.

<script lang="ts">
    import { dev } from "$app/environment";
    import { page } from "$app/state";
    import { PUBLIC_TURNSTILE_SITE_KEY } from "$env/static/public";
    import Button from "$lib/components/Button.svelte";
    import { toast } from "$lib/components/toast";
    import { clanApplicationSchema } from "$lib/schema";
    import { Control, Description, Field, FieldErrors } from "formsnap";
    import { Turnstile } from "svelte-turnstile";
    import SuperDebug, { superForm } from "sveltekit-superforms";
    import { zodClient } from "sveltekit-superforms/adapters";
    import info from "../../../data/info.json";
    import type { PageData } from "./$types";

    let { data }: { data: PageData } = $props();

    const form = superForm(data.form, {
        validators: zodClient(clanApplicationSchema),
        onUpdated() {
            reset?.();
        }
    });

    const { form: formData, enhance, message } = form;
    .....

    let reset = $state<() => void>();
</script>

<main class="flex size-full flex-col items-center justify-center">
.......
            <div class="flex items-center justify-center px-5 lg:w-1/2">
                <form method="POST" action="/apply" use:enhance class="flex w-full max-w-lg flex-col gap-2">
                    <Field {form} name="tag">
                        <Description>Your account tag (include #)</Description>
                        <Control>
                            {#snippet children({ props })}
                                <input {...props} type="text" placeholder="#ABCDEFGHI" bind:value={$formData.tag} class="rounded-xl text-gray-700" />
                            {/snippet}
                        </Control>
                        <FieldErrors class="text-red-400" />
                    </Field>
                    <Field {form} name="apiToken">
                        <Description>Your API token</Description>
                        <Control>
                            {#snippet children({ props })}
                                <input
                                    {...props}
                                    type="text"
                                    placeholder="API Token"
                                    bind:value={$formData.apiToken}
                                    class="rounded-xl text-gray-700"
                                />
                            {/snippet}
                        </Control>
                        <FieldErrors class="text-red-400" />
                    </Field>
                    <Field {form} name="cf-turnstile-response">
                        <Turnstile
                            class="text-center"
                            on:callback={(event) => {
                                $formData["cf-turnstile-response"] = event.detail.token;
                            }}
                            siteKey={PUBLIC_TURNSTILE_SITE_KEY}
                            bind:reset
                        />
                    </Field>
                    <button
                        disabled={buttonDisabled}
                        type="submit"
                        class="mt-4 rounded-xl bg-white px-4 py-3 text-gray-800 transition-all duration-200 hover:bg-gray-200 disabled:bg-gray-400"
                    >
                        Submit
                    </button>
                </form>
            </div>
        </div>
    {/if}
</main>

This is my schema

import { z } from "zod";

export const clanApplicationSchema = z.object({
    tag: z.string().min(5).startsWith("#"),
    apiToken: z.string().nonempty(),
    "cf-turnstile-response": z.string().nonempty()
});

And my +page.server.ts file

export const load: PageServerLoad = async ({ locals }) => {
    const user = locals.user;
    if (!user) {
        return redirect(302, "/");
    }

    return {
        form: await superValidate(zod(clanApplicationSchema)),
        user: user
    };
};

README.md Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants