feat(05): add blog/[...slug].vue — render @nuxt/content articles via queryCollection
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
---
|
||||
status: testing
|
||||
phase: 05-nuxt-content-setup-renderer
|
||||
source: [05-01-SUMMARY.md, 05-02-SUMMARY.md]
|
||||
started: 2026-04-21T00:00:00.000Z
|
||||
updated: 2026-04-21T00:00:00.000Z
|
||||
---
|
||||
|
||||
## Current Test
|
||||
|
||||
number: 3
|
||||
name: Images optimisées via NuxtImg
|
||||
expected: |
|
||||
Sur `/test`, l'image référencée dans l'article est visible (pas de 404).
|
||||
L'élément DOM rendu est `<img>` avec attribut `loading="lazy"`.
|
||||
awaiting: user response
|
||||
|
||||
## Tests
|
||||
|
||||
### 1. Serveur démarre sans erreur
|
||||
expected: `pnpm dev` lance Nuxt 4 sur :3000 sans erreur de console liée à @nuxt/content, SQLite ou @tailwindcss/typography. La page d'accueil se charge normalement.
|
||||
result: pass
|
||||
|
||||
### 2. Blocs de code toujours dark
|
||||
expected: Naviguer vers `/test`. Le bloc Kotlin affiché a un fond sombre (#0d1117) ET des tokens colorés — que ce soit en mode dark ou en mode light (toggle). En light mode, le fond du bloc reste sombre, pas blanc.
|
||||
result: pass
|
||||
|
||||
### 3. Images optimisées via NuxtImg
|
||||
expected: Sur `/test`, l'image référencée dans l'article est visible (pas de 404). Inspecter le DOM : l'élément rendu est `<img>` avec attribut `loading="lazy"`. ProseImg.vue est l'override utilisé.
|
||||
result: pass
|
||||
|
||||
### 4. Tableau markdown avec prose styling
|
||||
expected: Sur `/test`, le tableau markdown est rendu avec des bordures visibles, un en-tête distingué et une mise en forme prose correcte (pas du texte brut).
|
||||
result: pass
|
||||
|
||||
### 5. Callouts Alert (4 types)
|
||||
expected: Sur `/test`, les 4 callouts `::alert{type}` sont rendus comme des boîtes colorées avec icônes : info (bleu), warning (amber), tip (vert), danger (rouge).
|
||||
result: pass
|
||||
|
||||
### 6. Articles bilingues accessibles
|
||||
expected: Les articles de test existent pour FR et EN. Naviguer vers `/blog/test-kotlin-syntax` (FR) et `/en/blog/test-kotlin-syntax` (EN) — les deux pages chargent sans 404.
|
||||
result: [pending]
|
||||
|
||||
### 7. Collections @nuxt/content configurées
|
||||
expected: Le fichier `content.config.ts` définit `blog_fr` et `blog_en`. `queryCollection('blog_fr')` retourne les articles FR. Vérifiable via le bon rendu de `/test` (qui query `blog_fr`).
|
||||
result: [pending]
|
||||
|
||||
## Summary
|
||||
|
||||
total: 7
|
||||
passed: 0
|
||||
issues: 0
|
||||
pending: 7
|
||||
skipped: 0
|
||||
blocked: 0
|
||||
|
||||
## Gaps
|
||||
|
||||
[none yet]
|
||||
@@ -0,0 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
const { locale } = useI18n()
|
||||
const route = useRoute()
|
||||
|
||||
const slug = Array.isArray(route.params.slug) ? route.params.slug.join('/') : route.params.slug
|
||||
const path = `/blog/${slug}`
|
||||
|
||||
const { data: page } = await useAsyncData(`blog-${locale.value}-${slug}`, () => {
|
||||
const collection = locale.value === 'fr' ? 'blog_fr' : 'blog_en'
|
||||
return queryCollection(collection).path(path).first()
|
||||
})
|
||||
|
||||
if (!page.value) {
|
||||
throw createError({ statusCode: 404, statusMessage: 'Article introuvable' })
|
||||
}
|
||||
|
||||
useSeoMeta({
|
||||
title: page.value.title,
|
||||
description: page.value.description,
|
||||
ogTitle: page.value.title,
|
||||
ogDescription: page.value.description,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mx-auto max-w-3xl px-4 py-12">
|
||||
<article class="prose dark:prose-invert max-w-none">
|
||||
<ContentRenderer v-if="page" :value="page" />
|
||||
</article>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user