feat: update locale layout with Inter font, ThemeProvider, SEO metadata, JSON-LD, Header, and footer
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { Inter } from 'next/font/google'
|
||||
import { NextIntlClientProvider } from 'next-intl'
|
||||
import { getTranslations, getMessages } from 'next-intl/server'
|
||||
import { notFound } from 'next/navigation'
|
||||
import { ThemeProvider } from 'next-themes'
|
||||
import { routing } from '@/i18n/routing'
|
||||
import { LanguageSwitcher } from '@/components/LanguageSwitcher'
|
||||
import { Header } from '@/components/Header'
|
||||
import '../globals.css'
|
||||
|
||||
const inter = Inter({ subsets: ['latin', 'latin-ext'] })
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
@@ -12,7 +17,26 @@ export async function generateMetadata({
|
||||
}): Promise<Metadata> {
|
||||
const { locale } = await params
|
||||
const t = await getTranslations({ locale, namespace: 'meta' })
|
||||
return { title: t('title') }
|
||||
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL ?? ''
|
||||
|
||||
return {
|
||||
title: t('title'),
|
||||
description: t('description'),
|
||||
robots: { index: true, follow: true },
|
||||
openGraph: {
|
||||
title: t('title'),
|
||||
description: t('description'),
|
||||
url: `${baseUrl}/${locale}`,
|
||||
siteName: 'Ombrora',
|
||||
locale,
|
||||
},
|
||||
alternates: {
|
||||
canonical: `${baseUrl}/${locale}`,
|
||||
languages: Object.fromEntries(
|
||||
routing.locales.map((l) => [l, `/${l}`])
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default async function LocaleLayout({
|
||||
@@ -29,14 +53,44 @@ export default async function LocaleLayout({
|
||||
}
|
||||
|
||||
const messages = await getMessages()
|
||||
const t = await getTranslations({ locale, namespace: 'footer' })
|
||||
const baseUrl = process.env.NEXT_PUBLIC_BASE_URL ?? ''
|
||||
|
||||
const jsonLd = {
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'WebApplication',
|
||||
name: 'Ombrora',
|
||||
url: baseUrl,
|
||||
description: 'Free, fast, private video downloader.',
|
||||
applicationCategory: 'MultimediaApplication',
|
||||
operatingSystem: 'Web',
|
||||
offers: {
|
||||
'@type': 'Offer',
|
||||
price: '0',
|
||||
priceCurrency: 'EUR',
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<html lang={locale}>
|
||||
<body>
|
||||
<NextIntlClientProvider messages={messages}>
|
||||
<LanguageSwitcher />
|
||||
{children}
|
||||
</NextIntlClientProvider>
|
||||
<html lang={locale} suppressHydrationWarning>
|
||||
<head>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
</head>
|
||||
<body className={`${inter.className} bg-white dark:bg-slate-950 text-gray-900 dark:text-gray-50 antialiased min-h-screen flex flex-col`}>
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<NextIntlClientProvider messages={messages}>
|
||||
<Header />
|
||||
<div className="flex-1">
|
||||
{children}
|
||||
</div>
|
||||
<footer className="border-t border-gray-100 dark:border-slate-800 py-6 text-center text-sm text-gray-400 dark:text-slate-500">
|
||||
{t('copyright')}
|
||||
</footer>
|
||||
</NextIntlClientProvider>
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user