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

Handle hook doesn’t run on prerendered pages or static content in production #1862

Closed
malinowskip opened this issue Jul 9, 2021 · 12 comments · Fixed by #2178
Closed

Handle hook doesn’t run on prerendered pages or static content in production #1862

malinowskip opened this issue Jul 9, 2021 · 12 comments · Fixed by #2178
Labels
documentation Improvements or additions to documentation p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc.
Milestone

Comments

@malinowskip
Copy link
Contributor

malinowskip commented Jul 9, 2021

Describe the bug
The handle hook is not called when the app is built using the node adapter and when the server is run directly via node: node build/index.js.

To Reproduce

  1. Initialize the demo app with npm init svelte@next my-app.
  2. Install the node adapter: yarn add -D @sveltejs/adapter-node.
  3. Put node() in ./svelte.config.js in config.kit.adapter.
  4. Put a console log in the handle function in src/hooks.
  5. yarn build

If you run the application using node build/index.js, the hook is triggered only when you navigate to the /todos route.

Expected behavior
Things work correctly if you run the app with yarn preview, i.e. the hook is called on every page and on every refresh. I assume that this is the expected behavior.

Severity
This seems to break hooks in production.

Additional context
I haven’t tested this with other adapters.

Also doesn't work with static pages: #2060

@malinowskip
Copy link
Contributor Author

I assume that when a page is rendered in the browser, then the Node server is not called and the handle hook isn’t executed. I found and removed export const router = browser; from the /about page. After rebuilding, the hook was called when I navigated to the page. I guess that’s how it’s intended to work.

However, I wasn’t able to call the handle hook from the index page, even after I set router: false and ssr: true in the config.

@tw1t611
Copy link

tw1t611 commented Jul 9, 2021

Hi, which other routes do you have? If you are using parameterized routes (e.g. [slug]), you need to add the paths to kit.prerender.pages in svelte.config.js

@malinowskip
Copy link
Contributor Author

malinowskip commented Jul 10, 2021

My issue doesn't relate to prerendering (at least not directly). In fact, I don't want to prerender anything. The problem I ran into is that the handle hook, which should be called on each request, is ignored for some pages in the production (node) build. The app behaves differently in the adapter-agnostic preview mode vs. the final bundle compiled by the node adapter.

@malinowskip
Copy link
Contributor Author

Ok, I’ve made some progress.

  1. If a given page is prerendered, then it doesn’t trigger the handle hook in the node adapter bundle. I assume that’s not the expected behavior since it differs from what happens in preview mode.
  2. Builds are not properly invalidated by the node adapter. If I set prerender to false on a page and rebuild, the page’s old prerendered assets still remain in the build directory and cause the original issue described above (the handle hook doesn’t get called).

@benmccann benmccann added bug Something isn't working and removed pkg:adapter-node labels Jul 11, 2021
@benmccann benmccann added this to the 1.0 milestone Jul 11, 2021
@bleucitron

This comment has been minimized.

@benmccann

This comment has been minimized.

@benmccann benmccann changed the title Handle hook doesn’t run on every request in the production build Handle hook doesn’t run on prerendered pages or static content in production Aug 1, 2021
@benmccann benmccann added the p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc. label Aug 4, 2021
@malinowskip
Copy link
Contributor Author

I spent some more time looking into this and I think I found the cause.

The node adapter uses polka to process requests, passing each through a series of middleware. The final middleware calls the render function, which calls the respond function, which in turn is responsible for calling hooks.

Two preceding middleware functions are prerendered_handler and assets_handler, which use sirv to serve static assets. Sirv doesn’t call next() after it serves a static asset, so the middleware chain is halted before it reaches the final function.

@benmccann
Copy link
Member

@malinowskip can you clarify what your use case is? I asked Rich about this and he suggested it was working as intended. After a page has been rendered, is it still useful to call handle? What for?

We would at least need to update the docs though. Right now the first sentence is "this function runs on every request", which isn't strictly true

@malinowskip
Copy link
Contributor Author

Thanks, @benmccann. I was originally exploring SvelteKit’s client/server-side capabilities and tried to use the handle hook to log requests in a database. I thought that calling handle on each request might be useful for implementing server-side analytics. I imagine handle could be used to handle things like authorization.

We would at least need to update the docs though. Right now the first sentence is "this function runs on every request", which isn't strictly true

Yes, I agree. After initially reading the docs, I assumed that handle would run every time the server processed a request.

@benmccann
Copy link
Member

I imagine handle could be used to handle things like authorization

You're almost certainly won't prerender a page that can be logged into. If you want to display the logged in user, or a logout button, or anything else that might differ between visits then you can't prerender it

I thought that calling handle on each request might be useful for implementing server-side analytics

Hmm, yeah, that is a really good use case we should figure out how to support

@benmccann benmccann added documentation Improvements or additions to documentation and removed bug Something isn't working labels Aug 12, 2021
@benmccann
Copy link
Member

I think the best way to support that use case will be to use your adapter. E.g. for adapter-node we can expose a way to let you add middleware. I'll update the docs to clarify

@malinowskip
Copy link
Contributor Author

Thanks, I think that clarifies everything. The ability to add middleware to each request would be a cool feature to have in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation p1-important SvelteKit cannot be used by a large number of people, basic functionality is missing, etc.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants