feat(landing): translate landing page copy (Landing i18n namespace)
The landing page was hardcoded English, so switching languages had no visible effect on it — added a "Landing" namespace to both message catalogs and wired src/app/page.tsx up via getTranslations, matching the pattern already used by other server-rendered pages.
This commit is contained in:
1 parent
0da56a2aef
commit
f899ed5f7c
3 files changed
+52
-29
No files matched your search
@@ -500,5 +500,23 @@
|
||||
"confirm": "Blockieren",
|
||||
"successToast": "Du hast {petName} blockiert",
|
||||
"errorToast": "Tier konnte nicht blockiert werden. Bitte versuch es erneut."
|
||||
},
|
||||
"Landing": {
|
||||
"tagline": "Wo Haustiere die Stars sind. Profile, Beiträge und Storys — gemacht für Hunde, Katzen und Vögel.",
|
||||
"getStarted": "Jetzt loslegen",
|
||||
"logIn": "Anmelden",
|
||||
"previewAlt": "Der PawFeed-Feed mit Tierbeiträgen von Noctis und Bubi",
|
||||
"featuresHeading": "Gebaut für das Tier, nicht den Menschen",
|
||||
"feature1Title": "Nicht Menschen, sondern Tiere sind das Profil",
|
||||
"feature1Body": "Jeder Hund, jede Katze, jeder Vogel bekommt eine eigene Identität — eigene Beiträge, Follower und eine eigene Story, getrennt vom Besitzer.",
|
||||
"feature2Title": "Beiträge, Storys & Kurzvideos",
|
||||
"feature2Body": "Fotos, Kurzvideos und 24-Stunden-Storys — alles rund um das, was dein Tier gerade erlebt.",
|
||||
"feature3Title": "Gesundheits-Tracking",
|
||||
"feature3Body": "Gewichtsverlauf, Tierarztbesuche und Impfungen an einem Ort — per privatem Link mit dem Tierarzt teilbar.",
|
||||
"feature4Title": "Nachrichten von Tier zu Tier",
|
||||
"feature4Body": "Direktnachrichten laufen zwischen den Tieren, nicht den Besitzern — passend zum Aufbau der ganzen Plattform.",
|
||||
"footerImpressum": "Impressum",
|
||||
"footerDatenschutz": "Datenschutz",
|
||||
"footerAgb": "AGB"
|
||||
}
|
||||
}
|
||||
@@ -500,5 +500,23 @@
|
||||
"confirm": "Block",
|
||||
"successToast": "You've blocked {petName}",
|
||||
"errorToast": "Couldn't block this pet. Please try again."
|
||||
},
|
||||
"Landing": {
|
||||
"tagline": "Where pets are the stars. Profiles, posts, and stories — built for dogs, cats, and birds.",
|
||||
"getStarted": "Get started",
|
||||
"logIn": "Log in",
|
||||
"previewAlt": "The PawFeed feed, showing pet posts from Noctis and Bubi",
|
||||
"featuresHeading": "Built for the pet, not the person",
|
||||
"feature1Title": "Pets, not humans, are the profile",
|
||||
"feature1Body": "Every dog, cat, or bird gets its own identity — its own posts, followers, and story, separate from its owner's.",
|
||||
"feature2Title": "Posts, stories & short video",
|
||||
"feature2Body": "Photos, short-form video, and 24-hour stories — all built around what your pet is up to.",
|
||||
"feature3Title": "Health tracking",
|
||||
"feature3Body": "Weight logs, vet visits, and vaccine records in one place — shareable with a vet via a private link.",
|
||||
"feature4Title": "Pet-to-pet messaging",
|
||||
"feature4Body": "Direct messages happen between pets, not owners — matching how the whole platform is built.",
|
||||
"footerImpressum": "Imprint",
|
||||
"footerDatenschutz": "Privacy Policy",
|
||||
"footerAgb": "Terms"
|
||||
}
|
||||
}
|
||||
+16
-29
@@ -1,8 +1,9 @@
|
||||
import { auth } from "@clerk/nextjs/server";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { redirect } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { PawPrint, Sparkles, HeartPulse, MessageCircle, Images } from "lucide-react";
|
||||
import { PawPrint, HeartPulse, MessageCircle, Images } from "lucide-react";
|
||||
import { LanguageSwitcher } from "@/components/i18n/LanguageSwitcher";
|
||||
|
||||
/**
|
||||
@@ -21,27 +22,13 @@ export default async function RootPage() {
|
||||
const { userId } = await auth();
|
||||
if (userId) redirect("/feed");
|
||||
|
||||
const t = await getTranslations("Landing");
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: PawPrint,
|
||||
title: "Pets, not humans, are the profile",
|
||||
body: "Every dog, cat, or bird gets its own identity — its own posts, followers, and story, separate from its owner's.",
|
||||
},
|
||||
{
|
||||
icon: Images,
|
||||
title: "Posts, stories & short video",
|
||||
body: "Photos, short-form video, and 24-hour stories — all built around what your pet is up to.",
|
||||
},
|
||||
{
|
||||
icon: HeartPulse,
|
||||
title: "Health tracking",
|
||||
body: "Weight logs, vet visits, and vaccine records in one place — shareable with a vet via a private link.",
|
||||
},
|
||||
{
|
||||
icon: MessageCircle,
|
||||
title: "Pet-to-pet messaging",
|
||||
body: "Direct messages happen between pets, not owners — matching how the whole platform is built.",
|
||||
},
|
||||
{ icon: PawPrint, title: t("feature1Title"), body: t("feature1Body") },
|
||||
{ icon: Images, title: t("feature2Title"), body: t("feature2Body") },
|
||||
{ icon: HeartPulse, title: t("feature3Title"), body: t("feature3Body") },
|
||||
{ icon: MessageCircle, title: t("feature4Title"), body: t("feature4Body") },
|
||||
] as const;
|
||||
|
||||
return (
|
||||
@@ -71,7 +58,7 @@ export default async function RootPage() {
|
||||
</h1>
|
||||
|
||||
<p className="mx-auto mt-5 max-w-lg text-xl font-medium text-orange-50 sm:mx-0 sm:text-2xl">
|
||||
Where pets are the stars. Profiles, posts, and stories — built for dogs, cats, and birds.
|
||||
{t("tagline")}
|
||||
</p>
|
||||
|
||||
<div className="mt-10 flex flex-col justify-center gap-3 sm:flex-row sm:justify-start">
|
||||
@@ -79,13 +66,13 @@ export default async function RootPage() {
|
||||
href="/sign-up"
|
||||
className="inline-flex items-center justify-center rounded-xl bg-white px-7 py-3.5 text-base font-semibold text-orange-600 shadow-lg transition-colors hover:bg-orange-50"
|
||||
>
|
||||
Get started
|
||||
{t("getStarted")}
|
||||
</Link>
|
||||
<Link
|
||||
href="/log-in"
|
||||
className="inline-flex items-center justify-center rounded-xl border-2 border-white/70 px-7 py-3.5 text-base font-semibold text-white transition-colors hover:bg-white/10"
|
||||
>
|
||||
Log in
|
||||
{t("logIn")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -104,7 +91,7 @@ export default async function RootPage() {
|
||||
<div className="relative aspect-[16/10] w-full bg-muted">
|
||||
<Image
|
||||
src="/app-preview-feed.jpg"
|
||||
alt="The PawFeed feed, showing pet posts from Noctis and Bubi"
|
||||
alt={t("previewAlt")}
|
||||
fill
|
||||
sizes="(min-width: 768px) 896px, 100vw"
|
||||
className="object-cover object-left-top"
|
||||
@@ -119,7 +106,7 @@ export default async function RootPage() {
|
||||
<section className="bg-muted/30 px-6 py-20 sm:px-10">
|
||||
<div className="mx-auto max-w-5xl">
|
||||
<h2 className="text-center text-3xl font-bold tracking-tight text-foreground sm:text-4xl">
|
||||
Built for the pet, not the person
|
||||
{t("featuresHeading")}
|
||||
</h2>
|
||||
<div className="mt-14 grid gap-8 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{features.map(({ icon: Icon, title, body }) => (
|
||||
@@ -140,9 +127,9 @@ export default async function RootPage() {
|
||||
<div className="mx-auto flex max-w-5xl flex-col items-center justify-between gap-4 text-sm text-muted-foreground sm:flex-row">
|
||||
<span>© {new Date().getFullYear()} PawFeed</span>
|
||||
<nav className="flex gap-5">
|
||||
<Link href="/impressum" className="hover:text-foreground">Impressum</Link>
|
||||
<Link href="/datenschutz" className="hover:text-foreground">Datenschutz</Link>
|
||||
<Link href="/nutzungsbedingungen" className="hover:text-foreground">AGB</Link>
|
||||
<Link href="/impressum" className="hover:text-foreground">{t("footerImpressum")}</Link>
|
||||
<Link href="/datenschutz" className="hover:text-foreground">{t("footerDatenschutz")}</Link>
|
||||
<Link href="/nutzungsbedingungen" className="hover:text-foreground">{t("footerAgb")}</Link>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
Reference in new issue
Block a user