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.