Custom Routing in Nuxt 3 with Nuxt/content 3
I've been grappling with implementing custom routing in a Nuxt3 project for the past two days without success. The current website is built on WordPress and features dynamic URLs such as:
/parent-page-slug
(10 pages)
/traing-page-slug
(6)
/article-slug
(200+)
/testimonial-slug
(50+)
Each URL corresponds to a unique page design and will be managed using @nuxt/content
. Preserving the existing URL structure is crucial to maintain our current SEO rankings and backlinks.
Proposed Solution:
One approach I'm considering is placing all Markdown files in the content
directory without subfolders and creating a [slug].vue
file in the pages
directory. This file would conditionally render components based on a type
variable defined in the front matter of each Markdown file.
Directory Structure:
-| content/
---| parent-one.md
---| training-hello.md
---| article-1.md
---| testimonial-1.md
[slug].vue:
<template>
<ParentPage v-if="page.type==='parent'"/>
<TrainingPage v-if="page.type==='training'"/>
<ArticlePage v-if="page.type==='article'"/>
<TestimonialPage v-if="page.type==='testimonial'"/>
</template>
Alternative Consideration:
Alternatively, I'd prefer organizing the Markdown files into subdirectories within the content folder, such as parent training articles testimonials while retaining the existing URL structure. This would result in URLs like/one
, /running
, /dog
, /john
Directory Structure:
-| content/
---| parent
-----| one.md
---| training
-----| running.md
---| articles
-----| dog.md
---| testimonials
-----| john.md
Challenge:
The main challenge is defining custom routes that map these organized Markdown files to the desired flat URL structure without altering the existing URLs. I'm seeking guidance on how to achieve this in Nuxt3 and nuxt/content3
The slugs will be unique so if we have one in parent then we will not have it in other folders
Any suggestions would be appreciated
Thank you8 Replies
Hi @akhtarabbas5. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To implement custom routing in Nuxt 3 with Nuxt Content 3 while preserving your existing URL structure, you can use a combination of Nuxt's file-based routing and custom route configuration. Here's how you can approach this:
1. Organize your content:
Place your Markdown files in subdirectories within the
content
folder as you described in your alternative consideration. This organization will help you manage your content more effectively.
2. Create a catch-all route:
In your pages
directory, create a file named [...slug].vue
. This will act as a catch-all route for all your content types.
3. Use Nuxt Content to fetch the appropriate content:
In your [...slug].vue
file, use Nuxt Content's queryCollection
to fetch the content based on the current route.
Here's an example of how your [...slug].vue
file could look:
4. Configure Nuxt Content:
In your content.config.ts
file, define a collection that includes all your content:
This configuration tells Nuxt Content to treat all Markdown files as pages, regardless of their location in the content
directory.
5. Implement document-driven mode:
To ensure that your content is properly rendered and SEO-friendly, you can implement document-driven mode as described in the Nuxt Content documentation.
With this setup, your URLs will remain flat (e.g., /one
, /running
, /dog
, /john
) while your content is organized in subdirectories. The type
field in your Markdown frontmatter will determine which component is rendered for each page.
Remember to add the necessary type
field in the frontmatter of each Markdown file:
This approach allows you to maintain your existing URL structure while organizing your content in a more manageable way. It also provides flexibility for adding new content types in the future.
For more detailed information on custom routing in Nuxt 3, you can refer to the Nuxt documentation on custom routing.
Nuxt Content documentation provides additional details on working with content in Nuxt 3.
If you need to add any additional custom routes or modify the behavior further, you can use the pages:extend
hook in your nuxt.config.ts
file as described in the Nuxt documentation on adding custom routes.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@975722081088045079> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai but it will not render the page as the slug will be test-training but the .md file for it will be under /training folder
Let me check the knowledge base for you again. One moment! :books:
----------------------
You're right, and I apologize for the oversight in my previous answer. You're correct that with the setup I described, a URL like
/test-training
wouldn't automatically match a file located at /content/training/test-training.md
. Let's address this issue and provide a solution that works with your desired URL structure.
To solve this problem, we need to modify our approach slightly. Here's an updated solution that should work for your case:
1. Keep your content organized in subdirectories as you described.
2. In your [...slug].vue
file, we'll need to search all collections for the matching content. Here's how you can modify the script section:
This script will search for the content in all subdirectories until it finds a match.
3. Update your content.config.ts
to include all subdirectories:
This configuration tells Nuxt Content to include all Markdown files from the specified subdirectories.
4. In your nuxt.config.ts
, you might need to add some additional configuration to ensure proper handling of your routes:
This configuration helps with prerendering your routes and ensures that Nuxt Content can properly handle your custom routing structure.
With these modifications, your setup should now correctly handle URLs like /test-training
and match them to the corresponding Markdown files in the appropriate subdirectories.
Remember to adjust the collections array in the [...slug].vue
file if you add or remove any content subdirectories in the future.
This approach allows you to maintain your desired flat URL structure while keeping your content organized in subdirectories. It provides the flexibility you need for your different content types and preserves your existing URLs for SEO purposes.
Nuxt Content documentation provides more details on advanced usage and configuration options if you need to further customize this setup.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@975722081088045079> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
@kapa.ai I think it will effect the preformence as well have a lot of subdirectories in the content folder and and one another issue is we don't know how many files we will have so it's not possbile to add each url in nuxt.config
Let me check the knowledge base for you again. One moment! :books:
----------------------
You raise valid concerns about performance and scalability. Let's address these issues and propose a more efficient solution that doesn't require manually adding each URL to the
nuxt.config
file.
1. Performance Concerns:
You're right that searching through multiple subdirectories could potentially impact performance, especially as your content grows. To address this, we can use Nuxt Content's database capabilities more effectively.
2. Dynamic URL Handling:
Instead of manually adding URLs to nuxt.config
, we can use Nuxt's runtime configuration to dynamically handle route generation.
Here's an improved approach:
1. Flatten your content structure:
Instead of using subdirectories, keep all your Markdown files in the root of the content
directory. Use the type
field in the frontmatter to distinguish between different content types.
2. Update your content.config.ts
:
3. Modify your [...slug].vue
file:
4. Use runtime configuration for prerendering:
Instead of manually listing routes in nuxt.config.ts
, we can use a Nuxt plugin to dynamically generate routes for prerendering. Create a new file plugins/prerender-routes.ts
:
5. Update your nuxt.config.ts
:
This approach offers several advantages:
1. Better Performance: By flattening the content structure and using Nuxt Content's database querying, we avoid the need to search through multiple subdirectories.
2. Scalability: The plugin dynamically generates prerender routes based on your content, eliminating the need to manually update nuxt.config.ts
as your content grows.
3. Flexibility: You can still use the type
field in your Markdown frontmatter to distinguish between different content types, allowing for conditional rendering in your [...slug].vue
file.
This solution should provide better performance and scalability for your Nuxt 3 project with Nuxt Content 3, while maintaining your desired URL structure and SEO benefits.
For more information on optimizing performance with Nuxt Content, you can refer to the Nuxt Content documentation on performance.
Nuxt documentation on prerendering provides additional details on advanced prerendering configurations if you need further customization.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@975722081088045079> Kapa.ai is still learning and improving, please let me know how I did by reacting below.