layout.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import type { Metadata } from "next";
  2. import { Geist, Geist_Mono } from "next/font/google";
  3. import Script from "next/script";
  4. import React from "react";
  5. import "./globals.scss";
  6. import { SignalRProvider } from '@/contexts/signalrProvider';
  7. import { AuthProvider } from "@/contexts/authProvider";
  8. import { MemberProvider } from "@/contexts/memberProvider";
  9. import { ConfigProvider } from "@/contexts/configProvider";
  10. import { getAccessToken, getSignalRCryptoUrl, getSignalRChatUrl } from "@/lib/utils/server";
  11. import { fetchConfig } from "@/lib/api/system";
  12. const geistSans = Geist({
  13. variable: "--font-geist-sans",
  14. subsets: ["latin"],
  15. });
  16. const geistMono = Geist_Mono({
  17. variable: "--font-geist-mono",
  18. subsets: ["latin"],
  19. });
  20. export async function generateMetadata(): Promise<Metadata> {
  21. const config = (await fetchConfig())?.data;
  22. return {
  23. title: config?.basic?.siteName ?? 'bitforum',
  24. description: config?.meta?.description ?? '',
  25. keywords: config?.meta?.keywords ?? '',
  26. authors: config?.meta?.author ? [{ name: config.meta.author }] : undefined,
  27. applicationName: config?.meta.applicationName,
  28. generator: config?.meta.generator,
  29. robots: config?.meta.robots,
  30. other: {
  31. 'naver-site-verification': '18dc0d1c5cb466a765e5f5093f94638ed6537d1c',
  32. },
  33. };
  34. }
  35. export default async function RootLayout({
  36. children,
  37. }: Readonly<{
  38. children: React.ReactNode;
  39. }>) {
  40. const accessToken = await getAccessToken();
  41. const signalRCryptoUrl = await getSignalRCryptoUrl();
  42. const signalRChatUrl = await getSignalRChatUrl();
  43. const config = (await fetchConfig())?.data;
  44. return (
  45. <html lang="ko">
  46. <head>
  47. <link rel="manifest" href="/manifest.json" />
  48. <Script src="https://www.googletagmanager.com/gtag/js?id=G-DY6YFW4CTM" strategy="afterInteractive" />
  49. <Script id="gtag-init" strategy="afterInteractive">
  50. {`
  51. window.dataLayer = window.dataLayer || [];
  52. function gtag(){dataLayer.push(arguments);}
  53. gtag('js', new Date());
  54. gtag('config', 'G-DY6YFW4CTM');
  55. `}
  56. </Script>
  57. </head>
  58. <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
  59. <SignalRProvider accessToken={accessToken} signalRCryptoUrl={signalRCryptoUrl} signalRChatUrl={signalRChatUrl}>
  60. <AuthProvider>
  61. <MemberProvider>
  62. <ConfigProvider initialConfig={config}>
  63. {children}
  64. </ConfigProvider>
  65. </MemberProvider>
  66. </AuthProvider>
  67. </SignalRProvider>
  68. </body>
  69. </html>
  70. );
  71. }