In this detailed guide on using Links in the Next js application, we will cover various use cases on adding links for example:
- Internal Links
- External Links
- Passing Query or Path Parameters in Links
- Fetch Multiple Query Params in the URL
- Get or Set Dynamic Routes
- Styling Active Links
- Programmatically Navigate on Click
[lwptoc]
Let’s dive deep and learn with examples of each type of link:
Internal Links
Links between the pages of the application come under internal linking. To link between pages in a Next.js app, we use the Link
component from next/link
as shown below:
import Link from 'next/link';
function Nav() {
return (
<nav>
<Link href="/">
<a>Home</a>
</Link>
<Link href="/about">
<a>About</a>
</Link>
</nav>
);
}
The Link
component helps to prefetch the page in the background, so when a user clicks, it loads instantly.
Advantages of using Link components:
- The
Link
component is used instead of anchor tags to prevent page reloads. - We can wrap the
a
 tag insideÂLink
 to get styles/attributes. - Use the
href
prop to pass the page path. - Relative paths can be given starting with
/
.
External Links
Links to external sites or resources can be given by adding the native/ regular a
tags:
function Footer() {
return (
<footer>
<a href="https://www.example.com">Website</a>
</footer>
);
}
Passing Query or Path Parameters in Links
For dynamic pages, which can accept query or path params, we can pass those values in the Link as shown below inside the href:
<Link href="/blog/123?title=Next.js">
<a>Go to Blog 123</a>
</Link>
Or through the pathname:
<Link href="/blog/123/nextjs-is-awesome">
<a>Go to Blog 123</a>
</Link>
Get or Set Dynamic Routes
The query params or path params passed in the URL via link or any other method can be fetched by using the url.query
as shown below:
/post
which accepts a postId
parameter:// pages/post.js
export default function Post({ post }) {
return <div>{post.title}</div>
}
export async function getServerSideProps({ params }) {
const postId = params.postId;
const response = await fetch(`https://api.example.com/posts/${postId}`);
const post = await response.json();
return {
props: {
post
}
}
}
Now we can access the postId
parameter using url.query
in getServerSideProps
:
export async function getServerSideProps({ params }) {
// Access parameter
const postId = params.postId;
// Or access via url.query
const { postId } = params.url.query;
// Fetch post data
return {
props: {
post
}
}
}
To link to this page, we need to pass the postId
parameter:
<Link href="/post?postId=123">
<a>Post 123</a>
</Link>
The postId=123
query parameter will be available as params.url.query.postId
in getServerSideProps
.
Get or Set Dynamic Routes
Dynamic Routes are used to pass dynamic information to pages showing changing information like fetching data from remote API.
Create a pages/posts/[id].js
file to match dynamic ID values:
// pages/posts/[id].js
import { useRouter } from 'next/router';
export default function Post() {
const router = useRouter();
const { id } = router.query;
return <h1>Post {id}</h1>;
}
This will match any routes like /posts/1
, /posts/abc
etc. Then we can access the id
parameter from the router.
Next, we’ll implement getServerSideProps
to fetch the actual post data:
export async function getServerSideProps({ params }) {
const response = await fetch(`https://api.example.com/posts/${params.id}`);
const post = await response.json();
return {
props: {
post
}
};
}
To link to a dynamic page, we need to pass the ID dynamically:
<Link href="/posts/[id]" as={`/posts/${post.id}`}>
<a>{post.title}</a>
</Link>
The as
prop allows interpolating the value in the browser URL bar.
We can render the actual post data thereafter as shown below:
export default function Post({ post }) {
return (
<>
<h1>{post.title}</h1>
<p>{post.content}</p>
</>
);
}
Styling Active Links
It’s important to let users know about active links by highlighting them using CSS styles. In this section, we will get to know how to style the active links by checking the current URL route.
Here is a sample Navbar component with Link components:
import Link from 'next/link';
export default function Navbar() {
return (
<nav>
<Link href="/">
<a>Home</a>
</Link>
<Link href="/about">
<a>About</a>
</Link>
<Link href="/contact">
<a>Contact</a>
</Link>
</nav>
);
}
Next, we’ll import the useRouter
hook to access the router object:
import { useRouter } from 'next/router';
export default function Navbar() {
const router = useRouter();
// ... rest of component
}
We can now conditionally check the route and apply active styling:
<Link href="/">
<a className={router.pathname === '/' ? 'active' : ''}>Home</a>
</Link>
<Link href="/about">
<a className={router.pathname === '/about' ? 'active' : ''}>About</a>
</Link>
<style jsx>{`
.active {
color: red;
}
`}</style>
The active
class will be applied for the current page due to the route check. We can also use the activeClassName
prop directly on the Link:
<Link href="/" activeClassName="active">
<a>Home</a>
</Link>
<Link href="/about" activeClassName="active">
<a>About</a>
</Link>
This will automatically apply the class to the active link. Next we can add custom CSS style for active links
.active {
/* Styles */
color: red;
}
This allows styling the currently active link in your Next.js app!
Styling Dynamic Active Links
In the previous section, we got to know how to style some predefined links. But usually, we have dynamic build paths having query or path params. Let’s see how to add an active class on dynamic links:
Create the dynamic link:
<Link href="/post/[postId]/[category]" as={`/post/${post.id}/${post.category}`}>
<a>{post.title}</a>
</Link>
Next, in our Navbar component we can check the asPath
from router:
import { useRouter } from 'next/router'
export default function Navbar(){
const router = useRouter()
return (
<Link
href="/post/[postId]/[category]"
as={`/post/123/cars`}
activeClassName="active"
>
<a>Cars</a>
</Link>
)
}
To check if this link is active:
<Link
href="/post/[postId]/[category]"
as={`/post/123/cars`}
activeClassName={router.asPath.startsWith('/post/123/cars') ? 'active' : ''}
>
<a>Cars</a>
</Link>
We check if router asPath
starts with the link href.
Programmatically Navigate
Instead of adding Links in the template part, we can navigate programmatically via functions.
Import the useRouter
hook:
import { useRouter } from 'next/router';
Then access the router object:
export default function Home() {
const router = useRouter();
const handleClick = () => {
// Navigate programatically
}
return (
<button onClick={handleClick}>
Click to navigate
</button>
)
}
Now we can use the various router methods:
Navigate to a new page:
const handleClick = () => {
router.push('/about')
}
Replace current page:
const handleClick = () => {
router.replace('/contact')
}
Go back:
const handleClick = () => {
router.back()
}
Go forward (if history exists):
const handleClick = () => {
router.forward()
}
Pass Route Parameters
router.push('/post?id=123')
// Or with dynamic route
router.push('/post/[id]', '/post/123')
Conclusion
We discussed various ways to implement links inside templates or navigate pages programmatically. Also, we discussed how to get or set dynamic URL params including query or path parameters.
We discussed how to style the active links which are static or dynamic in nature. Hope this will be helpful…
Leave a Reply