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

Secure Your Vue.js 3 App: Laravel 11 Middleware with Pinia and Vue Router

Secure Your Vue.js 3 App: Laravel 11 Middleware with Pinia and Vue Router

Learn how to secure your Vue.js 3 app by creating custom Laravel 11 middleware, utilizing Pinia for state management, and implementing Vue Router guards for enhanced protection.
Mostafa Said
Mostafa Said
What is a Race Condition in Vue.js?

What is a Race Condition in Vue.js?

A race condition is where an app’s proper behavior is dependent on the sequence or timing of other uncontrollable events. In this lesson, learn how to fix a race condition in a Vue.js Composable.
Daniel Kelly
Daniel Kelly

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.