diff --git a/app/[locale]/(site)/contact/actions.ts b/app/[locale]/(site)/contact/actions.ts index 299197d..ea56502 100644 --- a/app/[locale]/(site)/contact/actions.ts +++ b/app/[locale]/(site)/contact/actions.ts @@ -5,7 +5,7 @@ import { isRedirectError } from "next/dist/client/components/redirect-error"; import { z } from "zod"; import { enforceContactRateLimit, verifyTurnstileToken } from "@/lib/contact-guard"; -import { getContactProtectionSettings } from "@/lib/app-config"; +import { getContactProtectionSettings, getSiteSettings } from "@/lib/app-config"; import { getLocalizedPath, resolveLocale } from "@/lib/locale"; import { sendContactMessage } from "@/lib/mail"; @@ -60,7 +60,8 @@ function getStringValue(formData: FormData, key: string) { export async function submitContactFormAction(formData: FormData) { const locale = resolveLocale(String(formData.get("locale") ?? "")); - const contactPath = getLocalizedPath(locale, "/contact"); + const siteSettings = await getSiteSettings(); + const contactPath = getLocalizedPath(locale, "/contact", siteSettings.defaultLocale); try { const protectionSettings = await getContactProtectionSettings(); @@ -86,7 +87,13 @@ export async function submitContactFormAction(formData: FormData) { message: values.message, }); - redirect(withMessage(getLocalizedPath(locale, "/success"), "success", contactSuccessMessages[locale])); + redirect( + withMessage( + getLocalizedPath(locale, "/success", siteSettings.defaultLocale), + "success", + contactSuccessMessages[locale], + ), + ); } catch (error) { if (isRedirectError(error)) { throw error; diff --git a/app/[locale]/(site)/contact/page.tsx b/app/[locale]/(site)/contact/page.tsx index f96e737..cec4578 100644 --- a/app/[locale]/(site)/contact/page.tsx +++ b/app/[locale]/(site)/contact/page.tsx @@ -7,7 +7,7 @@ import { PageHero } from "@/components/layout/page-hero"; import { MotionFade } from "@/components/motion-fade"; import { ContactForm } from "@/components/site/contact-form"; import { buildLocalizedMetadata } from "@/lib/metadata"; -import { getPublicContactProtectionSettings } from "@/lib/app-config"; +import { getPublicContactProtectionSettings, getSiteSettings } from "@/lib/app-config"; import { getLocalizedPath, resolveLocale } from "@/lib/locale"; import { AppCard } from "@/components/ui/app-card"; import { CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -36,9 +36,10 @@ export async function generateMetadata({ params }: ContactPageProps): Promise
{children}
- + ); } diff --git a/app/[locale]/(site)/page.tsx b/app/[locale]/(site)/page.tsx index b6d40f8..35f59ee 100644 --- a/app/[locale]/(site)/page.tsx +++ b/app/[locale]/(site)/page.tsx @@ -61,9 +61,10 @@ export async function generateMetadata({ params }: HomePageProps): Promise
diff --git a/app/[locale]/(site)/success/page.tsx b/app/[locale]/(site)/success/page.tsx index 1d1644e..31659bb 100644 --- a/app/[locale]/(site)/success/page.tsx +++ b/app/[locale]/(site)/success/page.tsx @@ -6,6 +6,7 @@ import { getTranslations } from "next-intl/server"; import { Container } from "@/components/layout/container"; import { MotionFade } from "@/components/motion-fade"; import { HeroShell, HeroTitle } from "@/components/layout/site-hero"; +import { getSiteSettings } from "@/lib/app-config"; import { buildLocalizedMetadata } from "@/lib/metadata"; import { getLocalizedPath, resolveLocale } from "@/lib/locale"; import { AppCard } from "@/components/ui/app-card"; @@ -34,7 +35,10 @@ export async function generateMetadata({ params }: SuccessPageProps): Promise @@ -51,10 +55,10 @@ export default async function SuccessPage({ params }: SuccessPageProps) {

diff --git a/app/[locale]/coming-soon/page.tsx b/app/[locale]/coming-soon/page.tsx index fcae30a..6826e12 100644 --- a/app/[locale]/coming-soon/page.tsx +++ b/app/[locale]/coming-soon/page.tsx @@ -35,7 +35,10 @@ export default async function ComingSoonPage({ }: ComingSoonPageProps) { const { locale } = await params; const localeKey = resolveLocale(locale); - const t = await getTranslations({ locale: localeKey, namespace: "comingSoon" }); + const [t, siteSettings] = await Promise.all([ + getTranslations({ locale: localeKey, namespace: "comingSoon" }), + getSiteSettings(), + ]); const isArabic = localeKey === "ar"; const lines = [ { @@ -57,7 +60,7 @@ export default async function ComingSoonPage({ return (
- + diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx index 0b2ee41..7d845a9 100644 --- a/app/[locale]/layout.tsx +++ b/app/[locale]/layout.tsx @@ -38,7 +38,7 @@ export default async function LocaleLayout({ const localeClassName = locale === "ar" ? "font-arabic" : "font-latin"; return ( - +
{children}
diff --git a/components/layout/floating-preferences.tsx b/components/layout/floating-preferences.tsx index 7e687bf..10ee6ea 100644 --- a/components/layout/floating-preferences.tsx +++ b/components/layout/floating-preferences.tsx @@ -9,11 +9,13 @@ import { cn } from "@/lib/utils"; type FloatingPreferencesProps = { locale: string; + defaultLocale: "de" | "en" | "ar"; className?: string; }; export function FloatingPreferences({ locale, + defaultLocale, className, }: FloatingPreferencesProps) { const t = useTranslations("navigation"); @@ -39,6 +41,7 @@ export function FloatingPreferences({ />
diff --git a/components/layout/locale-toggle.tsx b/components/layout/locale-toggle.tsx index 24030bc..b9744e7 100644 --- a/components/layout/locale-toggle.tsx +++ b/components/layout/locale-toggle.tsx @@ -17,6 +17,7 @@ const PENDING_TOAST_STORAGE_KEY = "mohfarawati-pending-toast"; type LocaleToggleProps = { locale: string; + defaultLocale?: AppLocale; className?: string; showLabel?: boolean; }; @@ -29,6 +30,7 @@ const localeChangedMessages: Record = { export function LocaleToggle({ locale, + defaultLocale = "de", className, showLabel = false, }: LocaleToggleProps) { @@ -82,7 +84,7 @@ export function LocaleToggle({ )} > { const message = localeChangedMessages[targetLocale]; diff --git a/components/layout/site-footer.tsx b/components/layout/site-footer.tsx index b85fc4e..453f266 100644 --- a/components/layout/site-footer.tsx +++ b/components/layout/site-footer.tsx @@ -2,7 +2,7 @@ import Link from "next/link"; import { useLocale, useTranslations } from "next-intl"; import { Container } from "@/components/layout/container"; -import { getLocalizedPath } from "@/lib/locale"; +import { AppLocale, getLocalizedPath } from "@/lib/locale"; const navItems = [ { key: "home", path: "" }, @@ -11,7 +11,11 @@ const navItems = [ { key: "contact", path: "/contact" }, ]; -export function SiteFooter() { +type SiteFooterProps = { + defaultLocale: AppLocale; +}; + +export function SiteFooter({ defaultLocale }: SiteFooterProps) { const locale = useLocale(); const tNav = useTranslations("navigation"); const tFooter = useTranslations("footer"); @@ -23,7 +27,7 @@ export function SiteFooter() { {navItems.map((item) => ( {tNav(item.key)} diff --git a/components/layout/site-header.tsx b/components/layout/site-header.tsx index 2aac186..688515a 100644 --- a/components/layout/site-header.tsx +++ b/components/layout/site-header.tsx @@ -34,6 +34,7 @@ const disabledMobileNavItemClassName = type SiteHeaderProps = { lightLogoUrl?: string | null; darkLogoUrl?: string | null; + defaultLocale: "de" | "en" | "ar"; }; function getDirectionalReveal(direction: "rtl" | "ltr") { @@ -57,9 +58,11 @@ function isNavItemActive(currentPath: string, itemPath: string) { } function NavLinks({ + defaultLocale, onNavigate, mobile = false, }: { + defaultLocale: "de" | "en" | "ar"; onNavigate?: () => void; mobile?: boolean; }) { @@ -113,7 +116,7 @@ function NavLinks({ return ( @@ -277,7 +281,7 @@ export function SiteHeader({ isArabic ? "w-auto max-w-none" : "min-w-[27rem] max-w-[42rem]", )} > - + @@ -293,6 +297,7 @@ export function SiteHeader({
) : (
diff --git a/lib/locale.ts b/lib/locale.ts index 8cca476..0f84347 100644 --- a/lib/locale.ts +++ b/lib/locale.ts @@ -28,8 +28,12 @@ export function stripLocalePrefix(pathname: string): string { return pathname || "/"; } -export function getLocalizedPath(locale: string, pathname = "/"): string { - return getLocalizedPathWithDefault(locale, pathname, routing.defaultLocale); +export function getLocalizedPath( + locale: string, + pathname = "/", + defaultLocale: AppLocale = routing.defaultLocale, +): string { + return getLocalizedPathWithDefault(locale, pathname, defaultLocale); } export function getLocalizedPathWithDefault( diff --git a/middleware.ts b/middleware.ts index 4d78d08..1c25008 100644 --- a/middleware.ts +++ b/middleware.ts @@ -196,9 +196,13 @@ export default async function middleware(request: NextRequest) { configuredDefaultLocale !== routing.defaultLocale && !hasLocalePrefix(pathname) ) { - const redirectUrl = request.nextUrl.clone(); - redirectUrl.pathname = getLocalizedPathWithDefault(configuredDefaultLocale, pathname, routing.defaultLocale); - return NextResponse.redirect(redirectUrl, 307); + const rewriteUrl = request.nextUrl.clone(); + rewriteUrl.pathname = getLocalizedPathWithDefault( + configuredDefaultLocale, + pathname, + routing.defaultLocale, + ); + return NextResponse.rewrite(rewriteUrl); } if (