0

I am trying to store the path into state of my app, so if the user is not logged in and is redirected to /login after logging in they can be directed to the correct path.

For example: Path = /posts/my-new post

What I am actually getting is posts/[pid] which obvious does not work when I try to redirect to.

import { useRouter } from 'next/router'
import { useState, useEffect } from 'react'

function App() {
  const router = useRouter()
  const [startUrl, setStartUrl] = useState(router.asPath)
  const [loggedIn, setLoggedIn] = useState(false)
  useEffect(() => {
    if (loggedIn) {
      router.push(startUrl)
    }
  },[loggedIn])
  return (
    <>
      <p>Path = {startUrl}</p>
    </>
  )
}
export default App
juliomalves
  • 42,130
  • 20
  • 150
  • 146
Dave Letorey
  • 31
  • 1
  • 4

2 Answers2

2

I found that the router was not ready immediately and hence I need to check that it is ready before setting the value.

I have added a storedURL boolean so this only happens on the first time.

import { useRouter } from 'next/router'
import { useState, useEffect } from 'react'

function App() {
  const router = useRouter()
  const [startUrl, setStartUrl] = useState("/")
  const [storedUrl, setStoredUrl] = useState("/")
  const [loggedIn, setLoggedIn] = useState(false)
  useEffect(() => {
    if (router.isReady && !storedURL) {
      setStartURL(router.asPath)
      setStoredURL(true)
    }
  },[router.isReady])
  useEffect(() => {
    if (loggedIn) {
      router.push(startUrl)
    }
  },[loggedIn])
  return (
    <>
      <p>Path = {startUrl}</p>
    </>
  )
}
export default App

This checks to see if the next/router hook isReady and that the URL has not already been stored (as otherwise it will update everytime the URL is changed)

Dave Letorey
  • 31
  • 1
  • 4
0

I think what you're going to want to do is store both the path, and the "query" for the current route, and push that into the router when the user has logged in.

I don't have a next.js project to test this with on hand, but I think if you change your code to what I have below it should work:


import { useRouter } from 'next/router'
import { useState, useEffect } from 'react'

function App() {
  const router = useRouter()
  const [startUrl, setStartUrl] = useState({
        pathname: router.asPath, 
        query: router.query
    })
  const [loggedIn, setLoggedIn] = useState(false)
  useEffect(() => {
    if (loggedIn) {
      router.push(startUrl)
    }
  },[loggedIn])
  return (
    <>
      <p>Path = {startUrl}</p>
    </>
  )
}
export default App

See the next.js useRouter() documentation for more info on the router.push() api as used with a URL object.

Dharman
  • 30,962
  • 25
  • 85
  • 135
MykalCodes
  • 164
  • 2
  • 12
  • 1
    Thank you @MykalCodes, I have found the issue. The problem is that next/router is not ready immediately and so this needs to be checked for first, I shall post my solution below. [next/router ready]{https://github.com/vercel/next.js/issues/8259} – Dave Letorey Mar 10 '22 at 12:00