diff --git a/client/index.js b/client/index.js index 55f9e052..0a08779c 100644 --- a/client/index.js +++ b/client/index.js @@ -29,6 +29,8 @@ const { location } = window +const asPath = getURL() + const pageLoader = new PageLoader(buildId, assetPrefix) window.__NEXT_LOADED_PAGES__.forEach(({ route, fn }) => { pageLoader.registerPage(route, fn) @@ -56,7 +58,7 @@ export default async () => { Component = ErrorComponent } - router = createRouter(pathname, query, getURL(), { + router = createRouter(pathname, query, asPath, { pageLoader, Component, ErrorComponent, @@ -107,7 +109,7 @@ export async function renderError (error) { console.error(errorMessage) if (prod) { - const initProps = { err: error, pathname, query } + const initProps = { err: error, pathname, query, asPath } const props = await loadGetInitialProps(ErrorComponent, initProps) ReactDOM.render(createElement(ErrorComponent, props), errorContainer) } else { @@ -120,8 +122,8 @@ async function doRender ({ Component, props, hash, err, emitter }) { Component !== ErrorComponent && lastAppProps.Component === ErrorComponent) { // fetch props if ErrorComponent was replaced with a page component by HMR - const { pathname, query } = router - props = await loadGetInitialProps(Component, { err, pathname, query }) + const { pathname, query, asPath } = router + props = await loadGetInitialProps(Component, { err, pathname, query, asPath }) } if (emitter) { diff --git a/lib/router/index.js b/lib/router/index.js index faec82cc..1efaf3e9 100644 --- a/lib/router/index.js +++ b/lib/router/index.js @@ -13,7 +13,7 @@ const SingletonRouter = { } // Create public properties and methods of the router in the SingletonRouter -const propertyFields = ['components', 'pathname', 'route', 'query'] +const propertyFields = ['components', 'pathname', 'route', 'query', 'asPath'] const coreMethodFields = ['push', 'replace', 'reload', 'back', 'prefetch'] const routerEvents = ['routeChangeStart', 'beforeHistoryChange', 'routeChangeComplete', 'routeChangeError'] diff --git a/lib/router/router.js b/lib/router/router.js index 8b1a4263..3fde1c98 100644 --- a/lib/router/router.js +++ b/lib/router/router.js @@ -27,7 +27,7 @@ export default class Router { this.ErrorComponent = ErrorComponent this.pathname = pathname this.query = query - this.as = as + this.asPath = as this.subscriptions = new Set() this.componentLoadCancel = null this.onPopState = this.onPopState.bind(this) @@ -190,7 +190,7 @@ export default class Router { } const { Component } = routeInfo - const ctx = { pathname, query } + const ctx = { pathname, query, asPath: as } routeInfo.props = await this.getInitialProps(Component, ctx) this.components[route] = routeInfo @@ -229,13 +229,13 @@ export default class Router { this.route = route this.pathname = pathname this.query = query - this.as = as + this.asPath = as this.notify(data) } onlyAHashChange (as) { - if (!this.as) return false - const [ oldUrlNoHash ] = this.as.split('#') + if (!this.asPath) return false + const [ oldUrlNoHash ] = this.asPath.split('#') const [ newUrlNoHash, newHash ] = as.split('#') // If the urls are change, there's more than a hash change diff --git a/readme.md b/readme.md index 8760c6ef..a540ff23 100644 --- a/readme.md +++ b/readme.md @@ -238,6 +238,7 @@ export default Page - `pathname` - path section of URL - `query` - query string section of URL parsed as an object +- `asPath` - the actual url path - `req` - HTTP request object (server only) - `res` - HTTP response object (server only) - `jsonPageRes` - [Fetch Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object (client only) @@ -283,6 +284,7 @@ Each top-level component receives a `url` property with the following API: - `pathname` - `String` of the current path excluding the query string - `query` - `Object` with the parsed query string. Defaults to `{}` +- `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 diff --git a/server/render.js b/server/render.js index 9678993b..75ac75a2 100644 --- a/server/render.js +++ b/server/render.js @@ -54,7 +54,8 @@ async function doRender (req, res, pathname, query, { ]) Component = Component.default || Component Document = Document.default || Document - const ctx = { err, req, res, pathname, query } + const asPath = req.url + const ctx = { err, req, res, pathname, query, asPath } const props = await loadGetInitialProps(Component, ctx) // the response might be finshed on the getinitialprops call diff --git a/test/integration/basic/pages/nav/as-path-using-router.js b/test/integration/basic/pages/nav/as-path-using-router.js new file mode 100644 index 00000000..e56634a1 --- /dev/null +++ b/test/integration/basic/pages/nav/as-path-using-router.js @@ -0,0 +1,22 @@ +import React from 'react' +import Router from 'next/router' + +export default class extends React.Component { + constructor (...args) { + super(...args) + this.state = {} + } + + componentDidMount () { + const asPath = Router.asPath + this.setState({ asPath }) + } + + render () { + return ( +