/opt/canhelp/apps/web/src/app
Edit: /opt/canhelp/apps/web/src/app/layout.tsx (4345B)
import type { Metadata } from 'next'
import { cookies, headers } from 'next/headers'
import { cache } from 'react'
import './globals.css'
import { Header } from '@/components/Header'
import { Footer } from '@/components/Footer'
import { LocaleProvider } from '@/context/locale'
import { LocationProvider } from '@/context/location'
import { ScrollToTopButton } from '@/components/ScrollToTopButton'
import { AdminRolePreview } from '@/components/AdminRolePreview'
import type { Locale } from '@/lib/translations'
// React.cache() deduplicates identical calls within the same request render pass
const fetchSeoSettings = cache(async (): Promise
> => {
try {
const apiBase = process.env.INTERNAL_API_URL || 'http://localhost:4000'
const res = await fetch(`${apiBase}/api/admin/seo-public`, { next: { revalidate: 60 } })
if (!res.ok) return {}
return res.json()
} catch {
return {}
}
})
export async function generateMetadata(): Promise {
const seo = await fetchSeoSettings()
const cookieStore = await cookies()
const rawLocale = cookieStore.get('canhelp_locale')?.value
const locale = ['el', 'en', 'ru', 'uk'].includes(rawLocale ?? '') ? rawLocale! : 'el'
const title =
seo[`seo.siteTitle.${locale}`] ||
seo['seo.siteTitle.el'] ||
seo['seo.siteTitle'] ||
'CanHelp — Βρες ειδικό για κάθε δουλειά'
const description =
seo[`seo.siteDescription.${locale}`] ||
seo['seo.siteDescription.el'] ||
seo['seo.siteDescription'] ||
'Η ελληνική πλατφόρμα για online ανάθεση εργασιών. Βρες επαγγελματίες για καθαρισμό, υδραυλικά, μαθήματα και πολλά άλλα.'
return {
title,
description,
keywords: 'εργασίες, ειδικοί, Ελλάδα, freelance, καθαρισμός, υδραυλικά',
robots: seo['seo.indexingEnabled'] === 'false' ? 'noindex, nofollow' : undefined,
}
}
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const cookieStore = await cookies()
const headerStore = await headers()
const pathname = headerStore.get('x-pathname') ?? ''
const isStandalone = pathname.startsWith('/site/')
const rawLocale = cookieStore.get('canhelp_locale')?.value
const locales: Locale[] = ['el', 'en', 'uk', 'ru']
const initialLocale: Locale = locales.includes(rawLocale as Locale)
? (rawLocale as Locale)
: 'el'
const initialLocation = decodeURIComponent(cookieStore.get('canhelp_location')?.value ?? '')
const seo = await fetchSeoSettings()
const headScripts = seo['seo.headScripts'] ?? ''
// Parse each