1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Make router properties update when re-rendering (#4541)

* Make router properties update when re-rendering

* Remove documentation about methods that have been deprecated since v2/v3

* Update next export documentation
This commit is contained in:
Tim Neutkens 2018-06-05 17:10:28 +02:00 committed by GitHub
parent a7bb9175eb
commit 5bc3b23c23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 20 deletions

View file

@ -14,11 +14,12 @@ const SingletonRouter = {
} }
// Create public properties and methods of the router in the SingletonRouter // Create public properties and methods of the router in the SingletonRouter
const propertyFields = ['components', 'pathname', 'route', 'query', 'asPath'] const urlPropertyFields = ['pathname', 'route', 'query', 'asPath']
const propertyFields = ['components']
const routerEvents = ['routeChangeStart', 'beforeHistoryChange', 'routeChangeComplete', 'routeChangeError', 'hashChangeStart', 'hashChangeComplete'] const routerEvents = ['routeChangeStart', 'beforeHistoryChange', 'routeChangeComplete', 'routeChangeError', 'hashChangeStart', 'hashChangeComplete']
const coreMethodFields = ['push', 'replace', 'reload', 'back', 'prefetch', 'beforePopState'] const coreMethodFields = ['push', 'replace', 'reload', 'back', 'prefetch', 'beforePopState']
propertyFields.forEach((field) => { propertyFields.concat(urlPropertyFields).forEach((field) => {
// Here we need to use Object.defineProperty because, we need to return // Here we need to use Object.defineProperty because, we need to return
// the property assigned to the actual router // the property assigned to the actual router
// The value might get changed as we change routes and this is the // The value might get changed as we change routes and this is the
@ -122,9 +123,19 @@ export function _rewriteUrlForNextExport (url) {
return newPath return newPath
} }
// This function is used to create the `withRouter` router instance
export function makePublicRouterInstance (router) { export function makePublicRouterInstance (router) {
const instance = {} const instance = {}
for (const property of urlPropertyFields) {
if (typeof router[property] === 'object') {
instance[property] = {...router[property]} // makes sure query is not stateful
continue
}
instance[property] = router[property]
}
propertyFields.forEach((field) => { propertyFields.forEach((field) => {
// Here we need to use Object.defineProperty because, we need to return // Here we need to use Object.defineProperty because, we need to return
// the property assigned to the actual router // the property assigned to the actual router

View file

@ -367,15 +367,11 @@ Client-side routing behaves exactly like the browser:
2. If it defines `getInitialProps`, data is fetched. If an error occurs, `_error.js` is rendered 2. If it defines `getInitialProps`, data is fetched. If an error occurs, `_error.js` is rendered
3. After 1 and 2 complete, `pushState` is performed and the new component is rendered 3. After 1 and 2 complete, `pushState` is performed and the new component is rendered
Each top-level component receives a `url` property with the following API: **Deprecated, use [withRouter](https://github.com/zeit/next.js#using-a-higher-order-component) instead** - Each top-level component receives a `url` property with the following API:
- `pathname` - `String` of the current path excluding the query string - `pathname` - `String` of the current path excluding the query string
- `query` - `Object` with the parsed query string. Defaults to `{}` - `query` - `Object` with the parsed query string. Defaults to `{}`
- `asPath` - `String` of the actual path (including the query) shows in the browser - `asPath` - `String` of the actual path (including the query) shows in the browser
- `push(url, as=url)` - performs a `pushState` call with the given url
- `replace(url, as=url)` - performs a `replaceState` call with the given url
The second `as` parameter for `push` and `replace` is an optional _decoration_ of the URL. Useful if you configured custom routes on the server.
##### With URL object ##### With URL object
@ -1419,16 +1415,35 @@ Note: we recommend putting `.next`, or your [custom dist folder](https://github.
<ul><li><a href="./examples/with-static-export">Static export</a></li></ul> <ul><li><a href="./examples/with-static-export">Static export</a></li></ul>
</details></p> </details></p>
This is a way to run your Next.js app as a standalone static app without any Node.js server. The export app supports almost every feature of Next.js including dynamic urls, prefetching, preloading and dynamic imports. `next export` is a way to run your Next.js app as a standalone static app without the need for a Node.js server.
The exported app supports almost every feature of Next.js, including dynamic urls, prefetching, preloading and dynamic imports.
The way `next export` works is by pre-rendering all pages possible to HTML. It does so based on a mapping of `pathname` key to page object. This mapping is called the `exportPathMap`.
The page object has 2 values:
- `page` - `String` the page inside the `pages` directory to render
- `query` - `Object` the `query` object passed to `getInitialProps` when pre-rendering. Defaults to `{}`
### Usage ### Usage
Simply develop your app as you normally do with Next.js. Then create a custom Next.js [config](https://github.com/zeit/next.js#custom-configuration) as shown below: Simply develop your app as you normally do with Next.js. Then run:
```
next build
next export
```
By default `next export` doesn't require any configuration. It will generate a default `exportPathMap` containing the routes to pages inside the `pages` directory.
If your application has dynamic routes you can add a dynamic `exportPathMap` in `next.config.js`.
This function is asynchronous and gets the default `exportPathMap` as a parameter.
```js ```js
// next.config.js // next.config.js
module.exports = { module.exports = {
exportPathMap: function(defaultPathMap) { exportPathMap: async function (defaultPathMap) {
return { return {
'/': { page: '/' }, '/': { page: '/' },
'/about': { page: '/about' }, '/about': { page: '/about' },
@ -1443,8 +1458,6 @@ module.exports = {
> Note that if the path ends with a directory, it will be exported as `/dir-name/index.html`, but if it ends with an extension, it will be exported as the specified filename, e.g. `/readme.md` above. If you use a file extension other than `.html`, you may need to set the `Content-Type` header to `text/html` when serving this content. > Note that if the path ends with a directory, it will be exported as `/dir-name/index.html`, but if it ends with an extension, it will be exported as the specified filename, e.g. `/readme.md` above. If you use a file extension other than `.html`, you may need to set the `Content-Type` header to `text/html` when serving this content.
In that, you specify what are the pages you need to export as static HTML.
Then simply run these commands: Then simply run these commands:
```sh ```sh
@ -1457,7 +1470,8 @@ For that you may need to add a NPM script to `package.json` like this:
```json ```json
{ {
"scripts": { "scripts": {
"build": "next build && next export" "build": "next build",
"export": "npm run build && next export"
} }
} }
``` ```
@ -1465,16 +1479,16 @@ For that you may need to add a NPM script to `package.json` like this:
And run it at once with: And run it at once with:
```sh ```sh
npm run build npm run export
``` ```
Then you've a static version of your app in the “out" directory. Then you have a static version of your app in the `out` directory.
> You can also customize the output directory. For that run `next export -h` for the help. > You can also customize the output directory. For that run `next export -h` for the help.
Now you can deploy that directory to any static hosting service. Note that there is an additional step for deploying to GitHub Pages, [documented here](https://github.com/zeit/next.js/wiki/Deploying-a-Next.js-app-into-GitHub-Pages). Now you can deploy the `out` directory to any static hosting service. Note that there is an additional step for deploying to GitHub Pages, [documented here](https://github.com/zeit/next.js/wiki/Deploying-a-Next.js-app-into-GitHub-Pages).
For an example, simply visit the “out” directory and run following command to deploy your app to [ZEIT now](https://zeit.co/now). For an example, simply visit the `out` directory and run following command to deploy your app to [ZEIT Now](https://zeit.co/now).
```sh ```sh
now now
@ -1482,11 +1496,11 @@ now
### Limitation ### Limitation
With next export, we build HTML version of your app when you run the command `next export`. In that time, we'll run the `getInitialProps` functions of your pages. With `next export`, we build a HTML version of your app. At export time we will run `getInitialProps` of your pages.
So, you could only use `pathname`, `query` and `asPath` fields of the `context` object passed to `getInitialProps`. You can't use `req` or `res` fields. The `req` and `res` fields of the `context` object passed to `getInitialProps` are not available as there is no server running.
> Basically, you won't be able to render HTML content dynamically as we pre-build HTML files. If you need that, you need run your app with `next start`. > You won't be able to render HTML dynamically when static exporting, as we pre-build the HTML files. If you want to do dynamic rendering use `next start` or the custom server API
## Multi Zones ## Multi Zones