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:

  1. Part 1 - Creating a new project with Nuxt, TailwindCSS, NuxtContent, Nuxt i18n
  2. 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>

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:

  1. Prepare translations for various page elements
  2. Create separate components for Hero, Features, and Footer
  3. Implement a language dropdown that changes the entire page language
  4. 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.