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
Updated: February 6th 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!
</script>

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).

Conclusion

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.

Related Courses

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.

Comments

Latest Vue School Articles

Generating Fake Data with Faker.js

Generating Fake Data with Faker.js

Discover the power of Faker.js, the essential JavaScript library for generating realistic fake data, in our new video course created in collaboration with the developers at Vehikl (vehikl.com).
Felipe Flor
Felipe Flor
Database Seeds with the Nuxt Task Runner

Database Seeds with the Nuxt Task Runner

Learn how to integrate Drizzle ORM with Nuxt for type-safe database operations, including database migrations and seeding with Faker.js and Nitro tasks.
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 200.000 users have already joined us. You are welcome too!

Follow us on Social

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