opral / inlang-paraglide-js

Tree-shakable i18n library build on the inlang ecosystem.
https://inlang.com/m/gerre34r/library-inlang-paraglideJs
48 stars 1 forks source link

Form on the homepage with named actions cannot use "use:enhance" #218

Open ludovicfourrage opened 1 month ago

ludovicfourrage commented 1 month ago

Using

Reproduction

  1. Setup a new or use an existing project
  2. On the homepage, add a simple form that uses "use:enhance":
    <form method="POST" action="?/subscribe" use:enhance>
    <label for="email">Subscribe to our newsletter</label>
    <input type="email" id="email" name="email" placeholder="Enter your email" required />
    <button type="submit">Subscribe</button>
    </form>
    {#if form?.success}
    <p>Welcome back {form.email}!</p>
    {/if}
  3. In +page.server.ts add the subscribe named action
    export const actions = {
    subscribe:  async ({request}) => {
    const data = await request.formData();
    const email = data.get('email');
    console.log('email', email);
    return { success: true, email };
    },
    } satisfies Actions;
  4. in /lib/i18n.ts set prefixDefaultLanguage to always
    export const i18n = createI18n(runtime, {
    prefixDefaultLanguage: "always",
    }
    )
  5. Test the form: it will post on the server, but the returned value won't be passed to the client-side "enhance".
  6. Changing prefixDefaultLanguage to "never" or using the default action will work.
samuelstroschein commented 1 month ago

Does the issue also appear if use:enhance is not used?

The prefix of the route with always ?/subscribe likely resolves in ?/en/subscribe , breaking the action. I would assume that use:enhance has no effect on the issue.

ludovicfourrage commented 1 month ago

Does the issue also appear if use:enhance is not used?

The prefix of the route with always ?/subscribe likely resolves in ?/en/subscribe , breaking the action. I would assume that use:enhance has no effect on the issue.

No, the issue does not appear when removing use:enhance

samuelstroschein commented 1 month ago

I see use:enhance interferes with routing under the hood. Ouch. I add this issue to the metaframework overhaul project https://github.com/opral/inlang-paraglide-js/issues/217

ludovicfourrage commented 1 month ago

I see use:enhance interferes with routing under the hood. Ouch. I add this issue to the metaframework overhaul project #217

Yes but good news there seem to be a workaround by explicitly calling applyAction as per https://kit.svelte.dev/docs/form-actions#progressive-enhancement.

Change the form to

      <form 
        method="POST"
        action="?/subscribe"
        use:enhance={handleEnhance}
      >

and add the handleEnhanced function in the script:

  const handleEnhance = ({ formElement, formData, action, cancel }: {
      formElement: HTMLFormElement;
      formData: FormData;
      action: URL;
      cancel: () => void;
    }) => {
    return async ({ result }: { result: ActionResult }) => {
      // `result` is an `ActionResult` object
      if (result.type === 'redirect') {
        goto(result.location);
      } else {
        await applyAction(result);
      }
    };
  };

This is only needed if the form is on the homepage by the way. Any other route seems to be working as expected without the workaround.