Skip to content

Commit

Permalink
writing: setting layout from route rules
Browse files Browse the repository at this point in the history
  • Loading branch information
mukundshah committed Sep 14, 2024
1 parent 35a7459 commit ac2e568
Showing 1 changed file with 80 additions and 0 deletions.
80 changes: 80 additions & 0 deletions content/writings/layouts-from-route-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: "Nuxt Recipe: Setting Layouts from Route Rules"
description: "A quick guide to dynamically setting layouts in Nuxt using route rules, with a custom module implementation."
publishedAt: 2024-09-14 20:45:36
readingMins: 5
---

## The Problem

In Nuxt, layouts are typically set in page components or via middleware. But what if you want to set layouts based on route rules for more dynamic control?

## The Solution

Here's a custom Nuxt module that allows setting layouts directly from route rules:

```typescript
import { defu } from 'defu'
import { defineNuxtModule } from 'nuxt/kit'
import { createRouter as createRadixRouter, toRouteMatcher } from 'radix3'

const declaration = `
import type { LayoutKey } from '#build/types/layouts'
declare module "nitropack" {
interface NitroRouteConfig {
layout?: LayoutKey | false
}
}`

export default defineNuxtModule({
meta: { name: 'route-rules-layout' },
setup(_, nuxt) {
const getRules = (url: string) => {
const _routeRulesMatcher = toRouteMatcher(
createRadixRouter({ routes: nuxt.options.routeRules })
)
return defu({}, ..._routeRulesMatcher.matchAll(url).reverse())
}

nuxt.hook('prepare:types', ({ declarations }) => {
declarations.push(declaration)
})

nuxt.hook('pages:extend', (pages) => {
pages.forEach((page) => {
const rules = getRules(page.path)
if (rules?.layout) {
page.meta ||= {}
page.meta.layout ??= rules.layout
}
})
})
},
})
```

## How to Use

1. Create a new file in your Nuxt project, e.g., `modules/route-rules-layout.ts`.
2. Paste the above code into this file.
3. In your `nuxt.config.ts`, add:

```typescript
export default defineNuxtConfig({
routeRules: {
'/admin/**': { layout: 'admin' },
'/blog/**': { layout: 'blog' },
// ... other route rules
}
})
```

Now, routes matching `/admin/**` will use the `admin` layout, and those matching `/blog/**` will use the `blog` layout.

## Considerations

- Test performance with large numbers of routes
- Be aware of conflicts with layouts set in page components
- Document this approach for your team

This recipe offers a flexible way to manage layouts in Nuxt, especially useful for projects with complex routing needs.

0 comments on commit ac2e568

Please sign in to comment.