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

[Question] How do you access the current URL in a component? #2019

Closed
nwshane opened this issue May 19, 2017 · 6 comments
Closed

[Question] How do you access the current URL in a component? #2019

nwshane opened this issue May 19, 2017 · 6 comments

Comments

@nwshane
Copy link

nwshane commented May 19, 2017

I want to create a LocaleLink component that navigates the user to the current page, but in the specified locale. The locale is part of the URL, so clicking on the "Deutsch" link while on the /en/posts/hurray-next-js page will take you to /de/posts/hurray-next-js.

In order to implement this LocaleLink component, I need to give it access to the current path. What's the best practice for passing the current path to LocaleLink? I can use window.location.pathname on the client side, but is that the best practice? And how can I get the pathname on the server side?

Thanks, and if this question doesn't belong here, let me know.

@Florian-R
Copy link

Florian-R commented May 19, 2017

@nwshane See #1708 (comment) I think this should do the job

EDIT: Also #194

@nwshane
Copy link
Author

nwshane commented May 20, 2017

@Florian-R Thanks for your answer, Florian. The method Router.asPath from 'next/router' looks like what I need, but I'm getting this error:

Error: No router instance found.
You should only use "next/router" inside the client side of your app.

It seems like the Router is only available on the client side? What's the best way to get the asPath value on the server side?

@nwshane
Copy link
Author

nwshane commented May 20, 2017

I managed to solve this already but with a rather inelegant solution. On the client side, I use Router.asPath. On the server side, I get context.req.originalUrl within the page's getInitialProps, and then set originalUrl on React's context (not the context object passed into getInitialProps, but the one described here), which I then subscribe to in my LocaleLink component.

Here's the relevant code from pages/myPage.js:

# pages/myPage.js
import React from 'react'
class MyPage extends React.Component {
  static async getInitialProps (context) {
      const { originalUrl } = context.req || {}

      return { originalUrl }
  }

  getChildContext () {
    const { originalUrl } = this.props
    return { originalUrl }
  }
  ...
}

MyPage.childContextTypes = {
  originalUrl: React.PropTypes.string
}

export default MyPage

And here's my LocaleLink component:

# components/LocaleLink.js
import Router from 'next/router'
import { PropTypes } from 'react'

const currentPath = (originalUrl) => {
  if (typeof window === 'object') {
    return Router.asPath
  } else {
    return originalUrl
  }
}

const newPath = ({locale}, {originalUrl}) => (
  currentPath(originalUrl).replace(/^\/\w\w/, `/${locale}`)
)

const LocaleLink = (props, context) => (
  <a href={newPath(props, context)}>
    {props.text}
  </a>
)

LocaleLink.contextTypes = {
  originalUrl: PropTypes.string
}

export default LocaleLink

Ideally, I would like to remove the dependency on React's context, as well as the need to check manually whether I'm on the server or client side to decide how to get the currentPath. Let me know if you have any ideas.

@arunoda
Copy link
Contributor

arunoda commented May 21, 2017

Actually, we already have the react context support for the router. We need to implement a public API for that.
See: #1960 (comment)

@arunoda
Copy link
Contributor

arunoda commented May 21, 2017

I think this question is already answered and we'll have a proper way to access the router with this: #2032

@fritz-c
Copy link

fritz-c commented Aug 31, 2017

This is achievable with the withRouter wrapper provided as of v3.2.1
https://github.com/zeit/next.js#using-a-higher-order-component

@lock lock bot locked as resolved and limited conversation to collaborators May 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants