kit icon indicating copy to clipboard operation
kit copied to clipboard

adapter-static: Allow root index.html to be served for dynamic paths

Open powellnorma opened this issue 1 year ago • 1 comments

Describe the problem

Let's say I have item/[id]/+page.svelte, which just contains:

<script lang="ts">
  import { page } from '$app/stores';

  $: itemId = $page.params.id;
</script>

<svelte:head>
  <title>Item {itemId}</title>
</svelte:head>

<h1>Item {itemId}</h1>
<p>This is the details page for item {itemId}.</p>

<a href="/">Back to Home</a>

Now I don't know all the itemIds in advance (and it also could be millions of different ones).

What works: Klicking on a link like <a href="./item/{Math.floor(Math.random() * 100) + 1}">Random Item</a> from the root page.

What doesn't work: Navigating to /item/123 directly - As there isn't a prerendered .html for this.

I tried serving index.html in that case, but it fails, since

  1. Relative paths are used:
Promise.all([
	import("./_app/immutable/entry/start.DsajyGCw.js"),
	import("./_app/immutable/entry/app.CUpY7-FC.js")
]).then(([kit, app]) => {
	kit.start(app, element);
});
  1. Even after fixing that path on the backend (to /_app/..), it now just gives a 404 page, the console says:
Error: Not found: /ui/item/6

In Routify this works without problems, it doesn't prerender individual pages, but expects you to always just serve the root index.html

Describe the proposed solution

Adjust the generated index.html file such that it can be served for any path.

Alternatives considered

On the backend, I currently rewrite the URL to /?jump-to-path=<somePath>, and in +layout.svelte I do:

onMount(() => {
  const jumpToPath = $page.url.searchParams.get('jump-to-path');
  if (jumpToPath) {
    // Remove the 'jump-to-path' parameter from the URL
    const newUrl = new URL($page.url);
    newUrl.searchParams.delete('jump-to-path');
    history.replaceState(null, '', newUrl);
                                                                 
    // Navigate to the specified path
    goto(jumpToPath, { replaceState: true });
  }
});

This works, but it flickers and requires extra code.

Importance

would make my life easier

Additional Information

In a real app, item/[id]/+page.svelte might fetch data dynamically via XHR. Implementing the proposed feature would make it easier to use svelte-kit without Node (e.g. when the backend is written in golang).

powellnorma avatar Oct 08 '24 13:10 powellnorma

If you want a dynamic route using the static adapter, you'll have to opt into SPA-mode (fetching the data when the page is mounted). You can do this by turning off prerendering for the dynamic route and specifying a fallback page option. https://kit.svelte.dev/docs/single-page-apps#usage

Does that fit your use case?

teemingc avatar Oct 16 '24 06:10 teemingc

I think @eltigerchino has the correct idea here -- if that doesn't work or you've still got issues:

  • npx sv create my-repro
  • git init && git add --all && git commit -m "Initial commit"
  • Add the code that minimally illustrates your issue
  • git add --all && git commit -m "Reproduce issue"
  • Create a repository on GutHub and upload your code
  • Open a new issue with the reproduction