How to Parse NextJS Query Params in Typescript
Jasser Mark Arioste
Hello, hustlers! In this article, we're going to learn how to parse and get fully-typed query parameters in a NextJS Typescript application.
There are three places where you might need to parse query parameters inside NextJS:
- On the frontend in a component or page.
- Inside
getServerSideProps
. - Inside a handler from
/api
route
Suppose your route is /posts?page=1&sort_by=popular&order_by=asc
. How do we parse this in different parts of the app? NextJS automatically does this for us, we just have to use different contexts.
Parsing Query Params Inside a Component or Page #
To parse query parameters within a component or page, you can use the useRouter
hook.
// posts.tsx const PostsPage = () => { const router = useRouter(); const query = router.query; console.log(query) // {page: "2", sort_by: "publishDate", sort_order: "desc" } return ( <div> <pre>{JSON.stringify(params, null, 4)}</pre> </div> ); };
1234567891011
If your app is small, this code would be fine. But if your app is huge and you're passing the query object to a child component, then it would be better to have types so that the child component knows what values or properties to expect. Let's modify our code:
import { useRouter } from "next/router"; import React from "react"; import { ParsedUrlQuery } from "querystring"; export interface PostPageQuery extends ParsedUrlQuery { page?: string; sort_by?: string; sort_order?: string; slug?: string; } const PostsPage = () => { const router = useRouter(); const query = router.query as PostPageQuery; return ( <div> <pre>{JSON.stringify(query, null, 4)}</pre> </div> ); };
123456789101112131415161718
Line 3: We import ParsedUrlQuery
. For now just don't mind this. I'll explain a bit more once we reach the API routes.
Lines 4-9: we define a PostPageQuery
interface that extends ParsedUrlQuery
. We write the parameters that we expect for this route. For the /posts
route, we expect page
, sort_by
and sort_order
.
Line 8: We use the as
operator to tell the compiler that router.query
is a PostPageQuery
type!
Now if in our VSCode editor, we'll have proper intellisense for the query. This helps alot in development so that we don't accidentally use sortBy
instead of sort_by
.
Parsing Inside getServerSideProps
#
It's pretty much the same inside getServerSideProps
. We still use the as
operator, the only difference is that, we use ctx.query
instead of router.query
:
export const getServerSideProps: GetServerSideProps = async (ctx) => { const query = ctx.query as PostPageQuery; console.log(query) // {page: "2", sort_by: "publishDate", sort_order: "desc" } return { props: {}, }; };
1234567
Parsing Inside an API Route #
Suppose your route is /api/posts?page=1&sort_by=popular&order_by=asc
. To parse it in typescript you can do the following:
import type { NextApiRequest, NextApiResponse } from "next"; import { PostPageQuery } from "pages/posts"; interface MyRequest extends NextApiRequest { query: PostPageQuery; } export default function handler(req: MyRequest, res: NextApiResponse) { const query = req.query; console.log(query) // {page: "2", sort_by: "publishDate", sort_order: "desc" } res.status(200).json({ query }); }
12345678910
If we check VSCode, our query is fully-typed with intellisense:
If we don't use ParsedUrlQuery
to extend PostPageQuery
,
// pages/posts.tsx export interface PostPageQuery { page?: string; sort_by?: string; sort_order?: string; slug?: string; }
1234567
We get a type error:
Is it Possible to Parse Query Params Inside getStaticProps
?
#
You can't parse query params inside getStaticProps
since the pages are generated at build time. The context does not have enough information about the incoming request at this point.
Conclusion #
We learned how to parse query parameters in NextJS. We also learned how to create fully-typed query parameters in Typescript. This leads to a better development experience as well as better maintainability for our NextJS application.
If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on Twitter.
Resources #
Credits: Image by Jörg Vieli from Pixabay