Skip to content
This repository was archived by the owner on Apr 6, 2023. It is now read-only.

feat(nuxt): payload rendering support#6455

Merged
pi0 merged 56 commits intomainfrom
feat/payload-jsonp
Sep 10, 2022
Merged

feat(nuxt): payload rendering support#6455
pi0 merged 56 commits intomainfrom
feat/payload-jsonp

Conversation

@pi0
Copy link
Copy Markdown
Member

@pi0 pi0 commented Aug 9, 2022

🔗 Linked issue

nuxt/nuxt#14507

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

This PR:

  • Adds new extension to renderer that by adding /_payload.js to the end of the URL, returning only payload chunk
  • Adds loadPayload(url, force?) composable
  • Adds prefetchPayload(url) composable
    • Server-side: Add link with modulepreload rel
    • Client-side: calls usePayload(url) to fill in the cache Same as server adds modulepreload to trigger browser prefetching in background
  • When using nuxt generate or prefetchPayload(url), it detect rendering mode based on headers and sets the x-nitro-prerender hint to prerender /[route]/_payload.js file
  • Add prerenderedAt to the payload when using prerendering or nuxt generate
  • Add isPrerendered composable (check active payload)

Testing:

Todo:

  • Cache prerender payload to avoid duplicate render
  • Replace payload from prerendered links to an external file
  • Add prerender header for prerendered pages
  • Load payload on navigation
  • Payload filtering for unassigned keys
  • Assign state on navigation
  • Run basic tests

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@netlify
Copy link
Copy Markdown

netlify Bot commented Aug 9, 2022

Deploy Preview for nuxt3-docs canceled.

Name Link
🔨 Latest commit 374429a
🔍 Latest deploy log https://app.netlify.com/sites/nuxt3-docs/deploys/631c978483f016000846ff76

Comment thread packages/nuxt/src/core/runtime/nitro/renderer.ts Outdated
Comment thread packages/nuxt/src/core/runtime/nitro/renderer.ts Outdated
@pi0 pi0 changed the title feat(nuxt): add payload js endpoint feat(nuxt): payload extraction support Aug 9, 2022
@pi0 pi0 mentioned this pull request Aug 9, 2022
6 tasks
@pi0 pi0 changed the title feat(nuxt): payload extraction support feat(nuxt): payload extraction and prerendering support Aug 9, 2022
@pi0 pi0 requested review from antfu, atinux and danielroe August 9, 2022 21:20
@pi0 pi0 changed the title feat(nuxt): payload extraction and prerendering support feat(nuxt): payload prerendering support Aug 9, 2022
Comment thread packages/nuxt/src/app/composables/payload.ts Outdated
Copy link
Copy Markdown
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

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

❤️ This looks great! Would be nice to see some tests as well.

Comment thread packages/schema/src/config/router.ts Outdated
Comment thread packages/nuxt/src/core/runtime/nitro/renderer.ts Outdated
Comment thread test/fixtures/basic/pages/random/[id].vue
@danielroe danielroe self-requested a review September 7, 2022 12:34
@danielroe
Copy link
Copy Markdown
Member

Mind if I push a test suite later this evening before merging?

@pi0 pi0 mentioned this pull request Sep 9, 2022
Copy link
Copy Markdown
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

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

Looks good to me!

Some suggestions for follow-up PRs:

  • enabling static in dev mode without the method I used in tests - user may have an API that can't be called from browser or relies on server-only api keys
  • hybrid mode (as you mention)
  • process.env.prerender - presumably we'll set this somehow in nitropack whilst prerendering?
  • would be nice to deduplicate payloads - e.g. if you hard load /random/a then it should 'fill' the payload and not redownload it when navigating from a -> b -> a.
  • [another note: would be nice to have support for testing generated or hybrid sites in test-utils - cc: @antfu]

@pi0
Copy link
Copy Markdown
Member Author

pi0 commented Sep 10, 2022

Thanks for helping to add tests @danielroe ❤️ Regarding your notes:

enabling static in dev mode without the method I used in tests - user may have an API that can't be called from browser or relies on server-only api keys

Later, with route rules, we could predict which routes are prerendered/static to adjust behavior. But note that payload rendering is not only for static mode (ie: server API keys available during prerendering phase. that should work in production too and with API fallback)

process.env.prerender - presumably we'll set this somehow in nitropack whilst prerendering?

It is already added and released from nitropack which I've used. If it doesn't work, not only is a performance issue but a security issue because an attacker could fill the memory of server by abusing payload cache. I plan to improve it later with a shared LRU.

would be nice to deduplicate payloads - e.g. if you hard load /random/a then it should 'fill' the payload and not redownload it when navigating from a -> b -> a.

Not quite sure to understand this. Payload state is fresh per page and payload URL is unique. We don't download by with but use dynamic import. Browsers have caching mechanism for esm imports and don't redownload. (unless using new hash to force download a new payload). Also note that we are splitting data/state from initial payload (runtime config and other top level keys)

would be nice to have support for testing generated or hybrid sites in test-utils

Do you mind to open an issue to elaborate more about your idea about possible utils?

Comment thread test/basic.test.ts Outdated
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants