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
/apiroute
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






