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!
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?
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 🙂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!
}
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(),
});
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!
});
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.
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!
© All rights reserved. Made with ❤️ by BitterBrains, Inc.