Route, link, and redirect content
Mount a collection, render it with a Nuxt page, and keep published URLs stable.
A page collection defines content routes. A Nuxt page component renders those routes.
Mount a collection
import { defineCollection, defineContentConfig } from '@lupinum/ginko-content/config'
export const changelog = defineCollection({
type: 'page',
source: 'changelog/*.md',
route: '/changelog'
})
export default defineContentConfig({ collections: { changelog } })content/changelog/1.0.md now resolves to the content path /changelog/1.0.
Add the Nuxt page
<script setup lang="ts">
import { createError } from '#imports'
import { changelog } from '~~/content.config'
definePageMeta({ key: route => route.path })
const { page: release } = await useContentPage(changelog)
if (!release.value) {
throw createError({ statusCode: 404, statusMessage: 'Release not found', fatal: true })
}
</script>
<template>
<ContentRenderer v-if="release" :value="release" />
</template>Ginko does not generate Vue page components. Nuxt still owns the application route and layout. A content route returns 404 until a Nuxt page matches it.
When the collection prefix is translated, declare one route mount per locale in content config instead of branching inside the page component.
Link to content
Link a queried document with route.resolvedPath, the resolved public path for that variant:
<NuxtLink :to="post.route.resolvedPath">
{{ post.title }}
</NuxtLink>Navigation and search results already expose a public path that can go straight into <NuxtLink>. canonicalKey, source filenames, and provider IDs identify content; they are not public URLs.
In Markdown, write the final root-relative public path:
[Get started](/docs/get-started/quickstart)Ginko checks root-relative links against final content URLs and concrete Nuxt routes. Set content.validation: 'error' to make a broken internal link fail the content build.
Redirect to the resolved URL
useContentPage does not redirect on its own. To send visitors to the resolved path, compare the requested and resolved paths and call navigateTo:
import { createError, navigateTo } from '#imports'
import { changelog } from '~~/content.config'
definePageMeta({ key: route => route.path })
const { page } = await useContentPage(changelog, { fallback: true })
if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Release not found', fatal: true })
}
const requested = page.value?.route.requestedPath
const resolved = page.value?.route.resolvedPath
if (requested && resolved && requested !== resolved) {
await navigateTo(resolved, { redirectCode: 301 })
}A locale fallback does not redirect automatically. The page decides whether to keep fallback content at the requested URL or send the visitor to the resolved path.
Move a published URL
When a published route changes, add a Nuxt or host redirect from the old URL to the new one. Do not keep a duplicate content file at the old path; that creates two documents instead of one redirect.