Join 13,567+ other Vue devs and get exclusive tips and insights delivered straight to your inbox, every week.
👋Hey friend! I work hard to send you amazing stuff each week.
— Michael
Hey!
I hope you're having a wonderful week.
Where I'm living in Waterloo, we've already had 140 cm of snow this February. That's almost as much snow in the last 3 weeks as we usually get in an entire winter.
I'm so tired from shoveling snow 🥲
This week I've been working on the lesson outlines for Mastering Nuxt while we get a new design done for the app that we build in the course.
And as always, I've got some tips and articles for you!
— Michael
I wanted to organize my blog content into several folders:
content/articles/
content/newsletters/
By default though, Nuxt Content would set up these routes to include those prefixes. But I want all of my routes to be at the root level:
We can do this manually for each Markdown file by overriding the _path
property through it's frontmatter:
---title: My Latest Articledate: today_path: "/my-latest-article"---
This is extremely tedious, error-prone, and generally annoying.
Luckily, we can write a simple Nitro plugin that will do this transform automatically.
Create a content.ts
file in server/plugins/
:
export default defineNitroPlugin((nitroApp) => {nitroApp.hooks.hook('content:file:afterParse', (file) => {for (const prefix of ['/articles', '/newsletters']) {if (file._path.startsWith(prefix)) {// Keep the prefix so we can query based on it stillfile._original_dir = prefix;// Remove prefix from pathfile._path = file._path.replace(prefix, '');}}});});
Nitro is the server that Nuxt uses internally. We can hook into it's processing pipeline and do a bit of tweaking.
However, doing this breaks queryContent
calls if we're filtering based on the path, since queryContent
is looking at the _path
property we've just modified. This is why we want to keep that original directory around.
We can modify our queryContent
calls to filter on this new _original_dir
property:
// BeforequeryContent('/articles')// AfterqueryContent().where({_original_dir: { $eq: '/articles' },});
Pro tip: use nuxi clean
to force Nuxt Content to re-fetch and re-transform all of your content.
Props down, events up. That's how your components should communicate — most of the time.
But in rare cases, that just doesn't work.
If you need direct access to the parent component, you should just use provide
/inject
to pass down the relevant value or method:
import { provide } from 'vue';const someMethodInTheParent = () => {};provide('method', someMethodInTheParent)
Then, inject it into the child component:
import { inject } from 'vue';const method = inject('method');method();
In Vue 2, you can also use the instance property $parent
:
// Tight coupling like this is usually a bad ideathis.$parent.methodOnParentComponent();
This is simpler, but leads to higher coupling and will more easily break your application if you ever refactor.
You can also get direct access to the application root, the very top-most component in the tree, by using $root
. Vue 2 also has $children
, but these were taken out for Vue 3 (please don't use this one).
When would these be useful?
There are a few different scenarios I can think of. Usually, when you want to abstract some behaviour and have it work "magically" behind the scenes.
You don't want to use props and events to connect up a component in those cases. Instead, you use provide
/inject
, $parent
, or $root
, to automatically connect the components and make things happen.
(This is similar to the Compound Component pattern)
But it's hard to come up with an example where this is the best solution. Using provide
/inject
is almost always the better choice.
One handy helper method in @nuxt/test-utils
is mockNuxtImport
.
It's a convenience method to make it easier to mock anything that Nuxt would normally auto-import:
import { mockNuxtImport } from '@nuxt/test-utils/runtime';mockNuxtImport('useAsyncData', () => {return () => {return { data: 'Mocked data' };};});// ...tests
If you've listened to the last episode, you know what is coming next!
It is time to get take a Vue at the other host of this podcast. Michael is asking Alex all around his past - from how we got into programming and web development, if university was worth it and how he got into the Nuxt Core Team.
Also don't miss out how Minecraft is part of the history, what non-tech job Alex would do if programming wouldn't be in the cards, and why is GitHub account is over 14 years old.
Watch on YouTube or listen on your favorite podcast platform.
Chapters:
In case you missed them:
You may have heard about server components, but there are some really interesting things you can do with them.
In this article I explore a few really cool things we can do with server components.
Check it out here: Exploring Server Components in Nuxt
Here are some upcoming events you might be interested in. Let me know if I've missed any!
The biggest Vue conference in the world! A two-day event with workshops, speakers from around the world, and socializing.
Giving a talk here on component patterns! A great Vue conference, this year held in Tampa. Two days of conference talks, plus a day for workshops.
It's time to get together in Madrid. Join for a full day of talks, activities, and networking with the Vue.js community and ecosystem.
"Sometimes the problem is to discover what the problem is." — Gordon Glegg
The best way to commit something to long-term memory is to periodically review it, gradually increasing the time between reviews 👨🔬
Actually remembering these tips is much more useful than just a quick distraction, so here's a tip from a couple weeks ago to jog your memory.
You can provide fallback content for a slot, in case no content is provided:
<!-- Child.vue --><template><div><slot>Hey! You forgot to put something in the slot!</slot></div></template>
This content can be anything, even a whole complex component that provides default behaviour:
<!-- Child.vue --><template><div><slot name="search"><!-- Can be overridden with more advanced functionality --><BasicSearchFunctionality /></slot></div></template>
Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.
p.s. I also have a bunch of products/courses: