You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
baer
wants to merge
3
commits into
vercel:canary
from
baer:feature/static-export-dynamic-routes-example
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Over the last year, I have used (and loved) Next.js to build several large React applications. I'm somewhat of an evangelist - it's an outstanding platform and an incredibly well-run project.
There is a body of uses cases, however, that are not well covered by the current examples or documentation: statically deployed applications where the data can't be determined at build time. Applications like these are common when page data is time-sensitive, too-large, user-specific, or can't reliably be fetched from a build server. Even when data is readily available, some developers prefer to use the App Shell Model, where an application bundle contains fully compiled, but empty, pages.
Despite my best efforts, Using Next.js for applications like this requires a fair amount of complexity. I'd like to use this PR as a place to discuss:
Whether this is a scenario that Next.js can/should/will support
What PRs are possible that could push some of this complexity into the framework
If the Zeit/Next.js team decides that additional work to make this easier is not a priority, this example at least gives some guidance to other developers who would like to try similar things.
Areas for discussion:
Note: I've already included most of these discussion points as comments in the code. I figured that, if the PR is merged ahead of or without changes to Next.js, these would be good guideposts for other developers.
Configuration for route translation
Applications with dynamically defined routes need configuration in three places:
next.config.js - The exportPathMap defines the set of routes to export
server.js - The development server needs the set of routes, and their translation into Next.js pages, in the Express path format
serve.json (or other CDN configuration) - The CDN needs the set of routes, and their translation into static paths, in the format required by that CDN
In my application, I've defined redirects in a file called redirects.js which I then read from Express and the next.config.js. I also use that file to generate the configuration for Serve.
Handling of URI parameters for static pages
When re-hydrating a statically compiled Next.js page, Next.js will ignore query parameters. For example, for the URL http://myapp.com?page=1, this.props.router.query is {}. The reason for this is that if Next.js were to process the parameters, React's virtual DOM might not match the statically rendered one which can cause React to fail in weird ways. One solution (proposed in #4341) is to trigger a second render if there are query parameters.
The Link tag
For dynamic pages (in a static application), using the Link component without an as property causes a full-page refresh. Since the symptom is, just a slightly slower page transition, this is an easy bug to introduce - especially now that the Next.js dev server compiles pages in real-time. Depending on whether your state (Redux, MobX, etc.) is stored in memory, and if performance is critical to your app, this could be anything from a non-issue to a show-stopper.
Again, thank you for your hard work and for your contributions the the ecosystem!
Apologies for the first commit, I hadn't installed git hooks, and it let me commit all of my files without running prettier and standard. It was just linty stuff :)
@chirag04 - thanks for your comment. No, there is no assumption that the data is static. The dynamic routes are generated from the Express.js-style routes in the redirects.js file, and the pages pull dynamic content on the client-side in componentDidMount. There is no reason you can't add static data with getInitialProps, like any other Next.js app, if you'd like.
baer
changed the title
Add example for static export with dynamic routes
Add example + discussion points: static export with dynamic routes
Apr 17, 2019
Hey @baer, I ended up writing #7355 based on this feedback and a bunch of other feedback 👍 Let's discuss more there if needed 👌
Over the last year, I have used (and loved) Next.js to build several large React applications. I'm somewhat of an evangelist - it's an outstanding platform and an incredibly well-run project.
vercel
locked as resolved and limited conversation to collaborators
Feb 1, 2022
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
None yet
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Over the last year, I have used (and loved) Next.js to build several large React applications. I'm somewhat of an evangelist - it's an outstanding platform and an incredibly well-run project.
There is a body of uses cases, however, that are not well covered by the current examples or documentation: statically deployed applications where the data can't be determined at build time. Applications like these are common when page data is time-sensitive, too-large, user-specific, or can't reliably be fetched from a build server. Even when data is readily available, some developers prefer to use the App Shell Model, where an application bundle contains fully compiled, but empty, pages.
Despite my best efforts, Using Next.js for applications like this requires a fair amount of complexity. I'd like to use this PR as a place to discuss:
If the Zeit/Next.js team decides that additional work to make this easier is not a priority, this example at least gives some guidance to other developers who would like to try similar things.
Areas for discussion:
Note: I've already included most of these discussion points as comments in the code. I figured that, if the PR is merged ahead of or without changes to Next.js, these would be good guideposts for other developers.
Configuration for route translation
Applications with dynamically defined routes need configuration in three places:
next.config.js
- TheexportPathMap
defines the set of routes to exportserver.js
- The development server needs the set of routes, and their translation into Next.js pages, in the Express path formatserve.json
(or other CDN configuration) - The CDN needs the set of routes, and their translation into static paths, in the format required by that CDNIn my application, I've defined redirects in a file called
redirects.js
which I then read from Express and thenext.config.js
. I also use that file to generate the configuration for Serve.Handling of URI parameters for static pages
When re-hydrating a statically compiled Next.js page, Next.js will ignore query parameters. For example, for the URL http://myapp.com?page=1,
this.props.router.query
is{}
. The reason for this is that if Next.js were to process the parameters, React's virtual DOM might not match the statically rendered one which can cause React to fail in weird ways. One solution (proposed in #4341) is to trigger a second render if there are query parameters.The Link tag
For dynamic pages (in a static application), using the Link component without an
as
property causes a full-page refresh. Since the symptom is, just a slightly slower page transition, this is an easy bug to introduce - especially now that the Next.js dev server compiles pages in real-time. Depending on whether your state (Redux, MobX, etc.) is stored in memory, and if performance is critical to your app, this could be anything from a non-issue to a show-stopper.Again, thank you for your hard work and for your contributions the the ecosystem!