Part 4 - Extending the Landing Page with nuxt/content and Multilingual Support
In this tutorial, we'll extend our landing page with a multilingual content page that displays Markdown files using the nuxt/content module.
15.09.2024
Introduction
In the previous parts of this series, we set up a Nuxt project, configured i18n, and implemented a landing page. In this fourth part, we'll extend our application with a multilingual content page that displays Markdown files using the nuxt/content module. We'll add a button to the landing page that links to this new content page and ensure that the content is displayed in the correct language.
Prerequisites
Make sure you've completed the previous parts of this series:
- Part 1 - Creating a new project with Nuxt, TailwindCSS, NuxtContent, Nuxt i18n
- Part 2 - Configuring nuxt/i18n
- Part 3 - Implementing a Landing Page with Nuxt and i18n
Step-by-Step Guide
Step 1: Preparing the Translations
First, we'll extend our translation files with the new content. Open the files locales/en-US.json
and locales/de-DE.json
and add the following content:
en-US.json:
{
"hero": {
// ... existing translations ...
"content_button": "View Content"
},
"content": {
"title": "Content Page",
"back_to_home": "Back to Home"
}
}
de-DE.json:
{
"hero": {
// ... existing translations ...
"content_button": "Inhalt anzeigen"
},
"content": {
"title": "Inhaltsseite",
"back_to_home": "Zurück zur Startseite"
}
}
Step 2: Adding the Content Button to the Hero Component
Open the file components/Hero.vue
and add the new button:
<template>
<section class="bg-blue-600 text-white py-20">
<div class="mx-auto px-4 w-full">
<div class="flex justify-between items-center">
<div class="w-2/3">
<h1 class="text-5xl font-bold mb-4">{{ $t('hero.title') }}</h1>
<p class="text-xl mb-8">{{ $t('hero.subtitle') }}</p>
<div class="space-x-4">
<button class="bg-white text-blue-600 py-2 px-6 rounded-full font-bold hover:bg-blue-100 transition duration-300">
{{ $t('hero.cta') }}
</button>
<NuxtLink
:to="localePath('/content')"
class="bg-blue-500 text-white py-2 px-6 rounded-full font-bold hover:bg-blue-400 transition duration-300">
{{ $t('hero.content_button') }}
</NuxtLink>
</div>
</div>
<div class="ml-auto">
<LanguageSelector />
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useLocalePath } from 'vue-i18n-routing'
import LanguageSelector from './LanguageSelector.vue'
const { t } = useI18n()
const localePath = useLocalePath()
</script>
Step 3: Creating the Content Page
Create a new file pages/content.vue
with the following content:
<template>
<div class="container mx-auto px-4 py-8">
<h1 class="text-3xl font-bold mb-4">{{ $t('content.title') }}</h1>
<ContentDoc :path="contentPath" class="prose lg:prose-lg" />
<NuxtLink
:to="localePath('/')"
class="mt-4 inline-block bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600 transition duration-300"
>
{{ $t('content.back_to_home') }}
</NuxtLink>
</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { useLocalePath } from 'vue-i18n-routing'
import { computed } from 'vue'
const { locale } = useI18n()
const localePath = useLocalePath()
const contentPath = computed(() => `/${locale.value}/content`)
</script>
Step 4: Creating Markdown Content
Create a new folder content
in the root directory of your project. In this folder, we'll create Markdown files for our content.
Create a subfolder for each supported language in the content
directory:
content/
en/
content.md
de/
content.md
Fill these files with the appropriate content in the respective language. For example:
content/en/content.md:
# Welcome to the Content Page
This is an example content rendered with nuxt/content.
## Features of nuxt/content
- Markdown support
- Automatic parsing
- Easy integration into Nuxt applications
Learn more about nuxt/content in the [official documentation](https://content.nuxtjs.org/).
content/de/content.md:
# Willkommen auf der Inhaltsseite
Dies ist ein Beispielinhalt, der mit nuxt/content gerendert wird.
## Funktionen von nuxt/content
- Markdown-Unterstützung
- Automatisches Parsing
- Einfache Integration in Nuxt-Anwendungen
Erfahre mehr über nuxt/content in der [offiziellen Dokumentation](https://content.nuxtjs.org/).
Step 5: Styling the Markdown Content
To ensure our Markdown content looks good, we'll add a TailwindCSS plugin:
npm install -D @tailwindcss/typography
Define this plugin in the tailwind.config.ts
file (if this file doesn't exist yet, please create it in the root folder):
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {},
},
plugins: [
require('@tailwindcss/typography'),
],
}
Now we can add the prose
TailwindCSS class to our ContentDoc
tag. It should look like this:
<ContentDoc class="prose lg:prose-lg" />
Step 6: Testing the Multilingual Content Page
Start the development server with npm run dev
and open http://localhost:3000
in your browser. You should now see the new "View Content" button on the landing page. Click on it to go to the content page, where you should see the rendered Markdown content in the currently selected language. Switch the language and check if the content updates accordingly.
Summary
In this fourth part of our series, we've successfully extended our landing page with a multilingual content page that displays Markdown files using the nuxt/content module. We've learned how to:
- Add a new button to the landing page that links to the content page
- Create a new page that displays the content of Markdown files
- Create and style Markdown content
- Manage multilingual content with nuxt/content and i18n
- Dynamically adapt the content page to the selected language
This extension provides a solid foundation for a multilingual content management system in your Nuxt application. In future tutorials, we could explore how to manage multiple content pages, add metadata to Markdown files, or implement more advanced features of nuxt/content.
You can find the code from this tutorial on Github.