Home / Blog / Zod and Query String Variables in Nuxt
Zod and Query String Variables in Nuxt

Zod and Query String Variables in Nuxt

Daniel Kelly
Daniel Kelly
February 5th 2024

We all know how important it is to validate the payloads of POST requests to our API endpoints and Zod makes this super easy to do! BUT did you know Zod is also super useful for working with data from the user’s query string variables?

Let me show you how to do this with your Nuxt apps!

How To Use Zod with Query Variables

Using zod to validate and get valid data from a query string in Nuxt is straightforward. Here is an example:

<script setup lang="ts">
import { z } from 'zod';
const route = useRoute();

// Define the expected shape of the query string data
const schema = z.object({
  q: z.string().optional(),
  page: z.coerce.number().optional().default(1),

// create a computed property with the zod parse method
// and the route.query object from Router
const validData = computed(() => {
  try {
    return schema.parse(route.query);
  } catch (e) {
    alert('invalid query string!');
    return null;

// 🎉 Now validData is guaranteed to be what you expect!

So, what are the benefits here?

Get Predictable Valid Data

First, I can rest assured the query string variables look like I’d expect them to. Check out these examples:

  • ?q=hello&q=world - errors because q is an array instead of a string
  • ?page=hello - errors because page is not a number
  • ?q=hello - The resulting data is{ q: 'hello', page: 1 } because q is a valid string and page is a default of 1
  • ?page=1 - The resulting data is { page: 1 } because page is a valid number (q isn’t provided but that’s ok, it’s marked optional)
  • ?page=2&q=hello - { q: "hello", page: 2 } - I think you get the picture 🙂

Ignore Useless Data

You know what query variables you expect, don’t clutter your validData with random query variables the user might insert into the query string. Using zod’s parse function eliminates any keys from the resulting data that aren’t defined in the schema.

// ?q=hello&page=1&extra=12  
  "q": "hello",
  "page": 1
  // "extra" property does not exist!

Coerce Query String Data

One of the most useful features of this strategy is that I never have to manually coerce data again. What do I mean? Query string values are ALWAYS strings (or arrays of strings). In times past, that meant calling parseInt whenever working with a number from the query string.

No more! Simply mark the variable with the coerce keyword in your schema, and zod does the conversion for you.

const schema = z.object({
  //       👇 right here
  page: z.coerce.number().optional(),

Default Values

Rely on a complete query variable object and stop checking whether or not values exist in the query string by providing defaults.

const schema = z.object({
    // ...
  page: z.coerce.number().optional().default(1), // 👈 default!

Practical Use Case

This is useful anywhere but I’ve found using this strategy especially helpful when dealing with all the ways you can paginate, sort, and filter data in a table. Easily store your states (like page, perPage, search query, sort by columns, etc in the query string and make your exact view of the table with particular datasets shareable via the URL).


In conclusion, this strategy for dealing with query strings pairs perfectly with any Nuxt application. Next time you accept data via the query string, consider using zod for a DX.

If you’d like live demo of this strategy, check out the following playground on StackBlitz.

Start learning Vue.js for free

Daniel Kelly
Daniel Kelly
Daniel is the lead instructor at Vue School and enjoys helping other developers reach their full potential. He has 10+ years of developer experience using technologies including Vue.js, Nuxt.js, and Laravel.

Latest Vue School Articles

Common Mistakes in Vue.js

Common Mistakes in Vue.js

In this blog article, we will explore some common mistakes developers make when working with Vue.js and provide practical advice on how to avoid them.
Daniel Kelly
Daniel Kelly
Lazy Hydration and Server Components in Nuxt &#8211; Vue.js 3 Performance

Lazy Hydration and Server Components in Nuxt – Vue.js 3 Performance

In the previous article, I mentioned two main ways that allow new, custom code to enter our Nuxt.js Application - components and plugins. Today, we will learn everything about the former. For most Nuxt.js applications, components are #1 contributor to the JavaScript bundle size.
Filip Rakowski
Filip Rakowski

Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.

More than 120.000 users have already joined us. You are welcome too!

Follow us on Social

© All rights reserved. Made with ❤️ by BitterBrains, Inc.