Part 3 - Implementing a Landing Page with Nuxt and i18n
This tutorial demonstrates how to implement a landing page using Nuxt, TailwindCSS, and i18n, including a hero section, feature section, and footer section with language switching.
08.09.2024
Introduction
In the previous parts of this series, we set up a Nuxt project and implemented the basic configuration for i18n. In this third part, we will implement a simple landing page with three main sections: a hero section, a feature section, and a footer section. Additionally, we will integrate a language dropdown in the hero section that allows changing the language of the entire page.
Prerequisites
Before we begin, make sure you have completed the previous parts of this series:
- Part 1 - Creating a new project with Nuxt, TailwindCSS, NuxtContent, Nuxt i18n
- Part 2 - Configuration of nuxt/i18n
Step-by-Step Guide
Step 1: Preparing the Translations
First, we need to expand our translation files to include the new content for our landing page. Open the files locales/en-US.json
and locales/de-DE.json
and add the following content:
en-US.json:
{
"hero": {
"title": "Welcome to Our Amazing App",
"subtitle": "Discover a new way of doing things",
"cta": "Get Started"
},
"features": {
"title": "Our Features",
"feature1": {
"title": "Easy to Use",
"description": "Our app is designed with simplicity in mind"
},
"feature2": {
"title": "Powerful",
"description": "Unlock the full potential of our tools"
},
"feature3": {
"title": "Secure",
"description": "Your data is safe with us"
}
},
"footer": {
"copyright": "© 2024 Amazing App. All rights reserved.",
"links": {
"privacy": "Privacy Policy",
"terms": "Terms of Service"
}
}
}
de-DE.json:
{
"hero": {
"title": "Willkommen bei unserer fantastischen App",
"subtitle": "Entdecke eine neue Art, Dinge zu erledigen",
"cta": "Jetzt loslegen"
},
"features": {
"title": "Unsere Funktionen",
"feature1": {
"title": "Einfach zu bedienen",
"description": "Unsere App wurde mit Blick auf Einfachheit entwickelt"
},
"feature2": {
"title": "Leistungsstark",
"description": "Nutze das volle Potenzial unserer Tools"
},
"feature3": {
"title": "Sicher",
"description": "Deine Daten sind bei uns sicher"
}
},
"footer": {
"copyright": "© 2024 Fantastische App. Alle Rechte vorbehalten.",
"links": {
"privacy": "Datenschutzrichtlinie",
"terms": "Nutzungsbedingungen"
}
}
}
Step 2: Creating the Landing Page Components
We will create separate components for each section of our landing page. Create a new folder called components
in your project directory if it doesn't already exist.
Hero Component
Create a new file components/Hero.vue
with the following content:
<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>
<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>
</div>
<div class="ml-auto">
<LanguageSelector />
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import LanguageSelector from './LanguageSelector.vue';
</script>
Feature Component
Create a new file components/Features.vue
:
<template>
<section class="py-20">
<div class="container mx-auto px-4">
<h2 class="text-3xl font-bold text-center mb-12">{{ $t('features.title') }}</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div v-for="i in 3" :key="i" class="bg-white p-6 rounded-lg shadow-md">
<h3 class="text-xl font-semibold mb-2">{{ $t(`features.feature${i}.title`) }}</h3>
<p>{{ $t(`features.feature${i}.description`) }}</p>
</div>
</div>
</div>
</section>
</template>
Footer Component
Create a new file components/Footer.vue
:
<template>
<footer class="bg-gray-800 text-white py-8">
<div class="container mx-auto px-4">
<div class="flex justify-between items-center">
<p>{{ $t('footer.copyright') }}</p>
<div>
<a href="#" class="mr-4 hover:text-blue-300">{{ $t('footer.links.privacy') }}</a>
<a href="#" class="hover:text-blue-300">{{ $t('footer.links.terms') }}</a>
</div>
</div>
</div>
</footer>
</template>
LanguageSelector Component
Create a new file components/LanguageSelector.vue
:
<template>
<select v-model="$i18n.locale" class="bg-white text-blue-600 py-2 px-4 rounded">
<option v-for="locale in $i18n.locales" :key="locale.code" :value="locale.code">
{{ locale.name }}
</option>
</select>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
const { locale, locales } = useI18n();
</script>
Step 3: Assembling the Landing Page
Now that we have created all the components, we can combine them in our main page. Open the file pages/index.vue
and replace the content with:
<template>
<div>
<Hero />
<Features />
<FooterComponent />
</div>
</template>
<script setup lang="ts">
import Hero from '~/components/Hero.vue';
import Features from '~/components/Features.vue';
import FooterComponent from '~/components/Footer.vue';
</script>
Step 4: Testing the Landing Page
Start the development server with npm run dev
and open http://localhost:3000
in your browser. You should now see your new landing page, complete with hero section, feature section, and footer. The language dropdown in the hero section should allow you to switch between German and English, with the entire content of the page changing accordingly.
Summary
In this third part of our series, we have successfully implemented a simple but effective landing page using Nuxt, TailwindCSS, and i18n. We have learned how to:
- Prepare translations for various page elements
- Create separate components for Hero, Features, and Footer
- Implement a language dropdown that changes the entire page language
- Assemble all components into a complete landing page
This foundation can now be further expanded and adapted to specific project requirements. In future tutorials, we could explore how to integrate the blog section using nuxt/content or implement more advanced i18n features.
You can find the code from this tutorial on Github.