mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-02 21:32:10 +03:00
- Add customFaviconUrl and customFaviconBase64 to Zod schema - Add favicon customization UI (URL input + file upload) - Create /api/settings/favicon endpoint for dynamic favicon - Update layout.tsx to use generateMetadata for dynamic favicon - Add i18n keys for favicon customization - Favicon updates browser tab icon in real-time
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import { Inter } from "next/font/google";
|
|
import "./globals.css";
|
|
import { ThemeProvider } from "@/shared/components/ThemeProvider";
|
|
import "@/lib/initCloudSync"; // Auto-initialize cloud sync
|
|
import { NextIntlClientProvider } from "next-intl";
|
|
import { getMessages, getLocale } from "next-intl/server";
|
|
import { RTL_LOCALES } from "@/i18n/config";
|
|
import { getSettings } from "@/lib/db/settings";
|
|
|
|
const inter = Inter({
|
|
subsets: ["latin"],
|
|
variable: "--font-inter",
|
|
});
|
|
|
|
export async function generateMetadata() {
|
|
const settings = await getSettings();
|
|
const instanceName = settings?.instanceName || "OmniRoute";
|
|
const customFaviconUrl = settings?.customFaviconUrl || settings?.customFaviconBase64;
|
|
|
|
return {
|
|
title: `${instanceName} — AI Gateway for Multi-Provider LLMs`,
|
|
description:
|
|
"OmniRoute is an AI gateway for multi-provider LLMs. One endpoint for all your AI providers.",
|
|
icons: {
|
|
icon: customFaviconUrl ? "/api/settings/favicon" : "/favicon.svg",
|
|
apple: "/apple-touch-icon.svg",
|
|
},
|
|
};
|
|
}
|
|
|
|
export default async function RootLayout({ children }) {
|
|
const locale = await getLocale();
|
|
const messages = await getMessages();
|
|
const isRtl = RTL_LOCALES.includes(locale as (typeof RTL_LOCALES)[number]);
|
|
|
|
return (
|
|
<html lang={locale} dir={isRtl ? "rtl" : "ltr"} suppressHydrationWarning>
|
|
<head>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
|
{/* eslint-disable-next-line @next/next/no-page-custom-font */}
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
</head>
|
|
<body className={`${inter.variable} font-sans antialiased`} suppressHydrationWarning>
|
|
<a
|
|
href="#main-content"
|
|
className="sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-50 focus:px-4 focus:py-2 focus:bg-[#6366f1] focus:text-white focus:rounded-lg focus:text-sm focus:font-semibold focus:shadow-lg"
|
|
>
|
|
Skip to content
|
|
</a>
|
|
<NextIntlClientProvider locale={locale} messages={messages}>
|
|
<ThemeProvider>{children}</ThemeProvider>
|
|
</NextIntlClientProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|