We can create server-side rendered React apps and static sites easily Next.js.
In this article, we’ll take a look at routing with Next.js.
Client-Side Navigation
In addition to routing on server-side, we can also do client-side navigation with Next.js.
For example, we can write:
pages/links.js
import { useRouter } from 'next/router'
function Links() {
const router = useRouter()
return (
<ul>
<li>
<span onClick={() => router.push('/foo')}>foo</span>
</li>
<li>
<span onClick={() => router.push('/bar')}>bar</span>
</li>
</ul>
)
}
export default Links
pages/foo.js
import Links from './links';
function Foo() {
return <div>
<Links />
<p>foo</p>
</div>
}
export default Foo
pages/bar.js
import Links from './links';
function Bar() {
return <div>
<Links />
<p>bar</p>
</div>
}
export default Bar
We have the pages/links.js file with spans that runs the router.push method on click.
The router object comes from Next.js’s useRouter hook.
Shallow Routing
Shallow routing lets us change the URL without running data fetching methods like getServerSideProps , getStaticProps , and getInitialProps again.
We get the updated pathname and query via the router object.
For example, we can write:
pages/count.js
import { useEffect } from 'react'
import { useRouter } from 'next/router'
function Count() {
const router = useRouter()
useEffect(() => {
router.push('/count?count=10', undefined, { shallow: true })
}, [])
useEffect(() => {
}, [router.query.count])
return <p>{router.query.count}</p>
}
export default Count
to add a Count component with a useEffect hook that calls router.push to add a query string to the URL.
shallow: true means that we enable shallow routing.
We should see 10 displayed since router.query.count is 10 as we see from the query string when we go to http://localhost:3000/count.
Shallow routing only works for same page URL changes.
So if we have:
router.push('/?count=10', '/about?count=10', { shallow: true })
then the about page would be loaded from scratch.
API Routes
We can use API routes to build an API with Next.js.
To do that , we can put JavaScrtipt files inside the pages/api folder.
Then the files inside would be mapped to the /api/* URLs.
For example, we can write:
pages/api/hello.js
export default (req, res) => {
res.statusCode = 200
res.json({ name: 'hello world' })
}
req has the requests data and res is an object we can use to create our response.
We set the response status code with res.statusCode and we create our JSON response with the res.json method.
Now when we make a request to http://localhost:3000/api/hello with any HTTP verb, we’ll see:
{
"name": "hello world"
}
returned.
To handle different HTTP methods, in an API route, we can use the req.method property.
For example, we can write:
export default (req, res) => {
res.statusCode = 200
res.json({ name: 'hello world', method: req.method })
}
Now when we make a PUT request to http://localhost:3000/api/hello, we get:
{
"name": "hello world",
"method": "PUT"
}
returned.
API routes don’t specify CORS headers, so we can only make these requests if the request originates from the same origin as the API route.
Conclusion
We can make API routes with Next.js.
Navigation can be done from the client side with the useRouter hook.