Skip to content

fix: skip calling respond for server-side fetch on prerendered pages - #13377

Merged
dummdidumm merged 6 commits into
sveltejs:mainfrom
aloisklink:fix/12739-fix-prerendered-routes-when-server-side-routing
Jan 30, 2025
Merged

fix: skip calling respond for server-side fetch on prerendered pages#13377
dummdidumm merged 6 commits into
sveltejs:mainfrom
aloisklink:fix/12739-fix-prerendered-routes-when-server-side-routing

Conversation

@aloisklink

@aloisklink aloisklink commented Jan 24, 2025

Copy link
Copy Markdown
Contributor

Server-side fetch() (e.g. when isSubRequest: true) currently has a few bugs when called on a prerendered route.

  1. When a non-prerendered route also matches the same URL as the prerendered route, the non-prerendered routes are taking precedence (e.g. if export const prerender = 'auto')
  2. Prerendered routes still have hooks.server.js run on them, but only when isSubRequest: true

I've fixed both of these issues by adding a prerendered_routes: Set<string> to the manifest. Then, we instantly call a real HTTP fetch() if the path matches, just like when calling server-side fetch() on assets (when the adapter doesn't support reading assets from the file-system).

During dev/build, there are no prerendered_routes, so it's left empty in the manifest (although that does mean the manifest-full.js also excludes it!)

Fixes #12778
Fixes #12739

Potential issues

  • According to the docs for prerendered.paths (which I'm using to set prerendered_routes), it only has the routes without a trailing slash. Would this be an issue? If so, the code might get a lot more complicated!
    /** An array of prerendered paths (without trailing slashes, regardless of the trailingSlash config) */
    paths: string[];
  • In the future, we might want to make a new entry like prerendered_redirects, so that we can follow the redirect chain without having to make a real HTTP request, but I think that should be fine if this is under the private _ field in the manifest.js file.

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check
    • pnpm test fails on main locally for me, so let's see if the CI passes on it!

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.
    • I've made two separate changesets for both the bugs I've fixed! Let me know if you want me to combine them (or if I should add more info to them, since I've just copied my commit message title, which are 50 chars long)

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

When using server-side fetch for internal requests, if a server route
is matched from the server `manifest.js`, it gets called without making
a real HTTP request.

However, prerendered routes are not included on this list! This is fine
when routes are prerendered with `export const prerender = true;`, but
will cause issues with a non-prerendered route also matches the same
URL as any prerendered routes.

This commit adds `prerendered_routes: Set<string>` to the `manifest.js`,
which skips calling the non-prerendered route.
Doing a server-side `fetch()` (e.g. `isSubRequest: true`) to a route
that is prerendered runs `hooks.server.js`,
which is different behaviour from a normal `fetch()`.
@changeset-bot

changeset-bot Bot commented Jan 24, 2025

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4b54db0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Comment thread packages/kit/src/core/adapt/builder.js Outdated
Comment thread packages/kit/src/core/generate_manifest/index.js Outdated
Comment thread packages/kit/src/core/generate_manifest/index.js Outdated
Comment thread packages/kit/src/core/adapt/builder.js Outdated
Comment thread packages/kit/src/exports/vite/index.js Outdated
Comment thread packages/kit/src/exports/vite/index.js Outdated
Comment thread packages/kit/src/exports/vite/index.js Outdated
@dummdidumm

dummdidumm commented Jan 29, 2025

Copy link
Copy Markdown
Member

Confirmed this also fixes #12778

Re the trailing slash problematics: that could indeed be problematic in the sense of you would get a false negative if you request /foo/ - I would say we just remove the trailing slash in this case. I cannot image anyone having a dynamic route on /foo/ but a prerendered one on /foo or vice versa.

Comment thread packages/kit/src/runtime/server/fetch.js Outdated

@dummdidumm dummdidumm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thank you!

@dummdidumm
dummdidumm merged commit d62ed39 into sveltejs:main Jan 30, 2025
@github-actions github-actions Bot mentioned this pull request Jan 30, 2025
@aloisklink

Copy link
Copy Markdown
Contributor Author

Thanks for handling the case where there is a trailing slash (and passing an array is a lot simpler!).

Re the trailing slash problematics: that could indeed be problematic in the sense of you would get a false negative if you request /foo/ - I would say we just remove the trailing slash in this case. I cannot image anyone having a dynamic route on /foo/ but a prerendered one on /foo or vice versa.

I was thinking of the same edge case 😆. I suspect it might happen due to a bug in somebody's code, but in the worst case, we're just adding the overhead of an extra HTTP call, so I doubt anybody would complain.

@aloisklink
aloisklink deleted the fix/12739-fix-prerendered-routes-when-server-side-routing branch January 30, 2025 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants