Next.js is a powerful React framework that simplifies the creation of web applications by providing a set of conventions and built-in functionalities. One of the key features of Next.js is its routing system, which allows developers to create pages and navigate between them with ease. With the introduction of typed routes, Next.js enhances the developer experience by providing type safety for routing, especially when using TypeScript.
Understanding Typed Routes in Next.js
Typed routes in Next.js are an experimental feature that provides statically typed links within your application. This feature is part of the Next.js App Router and requires TypeScript to be used in your project. The main advantage of typed routes is that they help ensure that the links within your application are correct at compile time, reducing the likelihood of runtime errors due to incorrect URLs or missing query parameters.
To enable typed routes in your Next.js project, you need to set the typedRoutes
option to true
in your next.config.js
file. Here's an example configuration:
// next.config.js
const nextConfig = {
experimental: {
typedRoutes: true,
},
};
module.exports = nextConfig;
This feature is still in beta and currently does not support rewrites and redirects. However, it is a significant step towards improving type safety in Next.js applications.
Using nextjs-routes
for Typed Routing
While the built-in typed routes feature in Next.js is still experimental, there is a third-party library called nextjs-routes
that provides type-safe routing for both the app directory and pages. This library scans your pages directory and generates route types based on your application's routes, ensuring that your links are type-safe with zero runtime overhead.
Installation and Setup
To use nextjs-routes
, you need to install the package and update your next.config.js
file as follows:
npm install nextjs-routes
# or
yarn add nextjs-routes
# or
pnpm add nextjs-routes
Then, update your next.config.js
:
// next.config.js
const nextRoutes = require("nextjs-routes/config");
const withRoutes = nextRoutes();
const nextConfig = {
reactStrictMode: true,
};
module.exports = withRoutes(nextConfig);
After running npx next dev
or npx next build
, a @types/nextjs-routes.d.ts
file will be generated, which augments the type definitions for next/link
and next/router
.
Examples of Typed Routing with nextjs-routes
Here are some examples of how you can use typed routing with nextjs-routes
:
Link Component
import Link from "next/link";
// Typed href based on your application routes
<Link
href={{
pathname: "/posts/[postId]",
query: { postId: "123" },
}}
>
Read Post
</Link>;
// For routes without parameters, you can use a string
<Link href="/about">About Us</Link>;
useRouter Hook
import { useRouter } from "next/router";
const router = useRouter();
// Typed push method
router.push({
pathname: "/posts/[postId]",
query: { postId: "456" },
});
// Typed replace method
router.replace("/");
// Typed query object
const { query } = useRouter();
// query is typed as a union of all query parameters defined by your application's routes
getServerSideProps
import type { GetServerSidePropsContext } from "nextjs-routes";
export function getServerSideProps(
context: GetServerSidePropsContext<"/posts/[postId]">
) {
// context.params will include `postId` as a string
const { postId } = context.params;
}
Custom Example: Typed Blog Post Routes
Let's create a custom example to illustrate how typed routes can be used in a practical scenario. Imagine we have a blog application with dynamic routes for individual blog posts. We want to ensure that our links to these posts are type-safe.
First, we define our blog post page under the pages/posts/[postId].tsx
file. Then, we use nextjs-routes
to generate the typed routes.
// pages/posts/[postId].tsx
import { useRouter } from "next/router";
import Link from "next/link";
const PostPage = () => {
const router = useRouter();
const { postId } = router.query as { postId: string };
return (
<div>
<h1>Post {postId}</h1>
<Link href="/posts">
<a>Back to posts</a>
</Link>
</div>
);
};
export default PostPage;
Now, when we link to a post, we can use the typed href
to ensure that we pass the correct postId
:
// pages/posts/index.tsx
import Link from "next/link";
const PostsList = ({ posts }) => {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<Link
href={{
pathname: "/posts/[postId]",
query: { postId: post.id },
}}
>
{post.title}
</Link>
</li>
))}
</ul>
);
};
export default PostsList;
With nextjs-routes
, if we accidentally mistype the route or forget to pass the required postId
, TypeScript will alert us at compile time, preventing potential runtime errors.
Conclusion
Typed routes in Next.js provide a robust way to ensure that your application's routing is type-safe, reducing the risk of errors and improving the developer experience. While the built-in typed routes feature in Next.js is still experimental, the nextjs-routes
library offers a stable solution that works with both the app directory and pages. By following the examples provided, you can implement typed routes in your Next.js projects and enjoy the benefits of type safety in your routing logic.
Remember to keep an eye on the Next.js documentation and release notes for updates on the typed routes feature as it moves towards stability. Happy coding!
Top comments (0)