layout.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import React from "react"
  2. import type { Metadata } from "next"
  3. import { Inter } from "next/font/google"
  4. import Script from "next/script"
  5. import { SEO } from "@/lib/seo"
  6. import { Providers } from "@/components/providers"
  7. import Shell from "./shell"
  8. import "./globals.css"
  9. const inter = Inter({ subsets: ["latin"] })
  10. export const metadata: Metadata = {
  11. metadataBase: new URL(SEO.url),
  12. title: {
  13. template: "%s | Roo Code",
  14. default: SEO.title,
  15. },
  16. description: SEO.description,
  17. alternates: {
  18. canonical: SEO.url,
  19. },
  20. icons: {
  21. icon: [
  22. { url: "/favicon.ico" },
  23. { url: "/favicon-16x16.png", sizes: "16x16", type: "image/png" },
  24. { url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
  25. ],
  26. apple: [{ url: "/apple-touch-icon.png" }],
  27. other: [
  28. {
  29. rel: "android-chrome-192x192",
  30. url: "/android-chrome-192x192.png",
  31. sizes: "192x192",
  32. type: "image/png",
  33. },
  34. {
  35. rel: "android-chrome-512x512",
  36. url: "/android-chrome-512x512.png",
  37. sizes: "512x512",
  38. type: "image/png",
  39. },
  40. ],
  41. },
  42. openGraph: {
  43. title: SEO.title,
  44. description: SEO.description,
  45. url: SEO.url,
  46. siteName: SEO.name,
  47. images: [
  48. {
  49. url: SEO.ogImage.url,
  50. width: SEO.ogImage.width,
  51. height: SEO.ogImage.height,
  52. alt: SEO.ogImage.alt,
  53. },
  54. ],
  55. locale: SEO.locale,
  56. type: "website",
  57. },
  58. twitter: {
  59. card: SEO.twitterCard,
  60. title: SEO.title,
  61. description: SEO.description,
  62. images: [SEO.ogImage.url],
  63. },
  64. robots: {
  65. index: true,
  66. follow: true,
  67. googleBot: {
  68. index: true,
  69. follow: true,
  70. "max-snippet": -1,
  71. "max-image-preview": "large",
  72. "max-video-preview": -1,
  73. },
  74. },
  75. keywords: [...SEO.keywords],
  76. applicationName: SEO.name,
  77. category: SEO.category,
  78. }
  79. export default function RootLayout({ children }: { children: React.ReactNode }) {
  80. return (
  81. <html lang="en" suppressHydrationWarning>
  82. <head>
  83. <link
  84. rel="stylesheet"
  85. type="text/css"
  86. href="https://cdn.jsdelivr.net/gh/devicons/devicon@latest/devicon.min.css"
  87. />
  88. </head>
  89. <body className={inter.className}>
  90. {/* Google tag (gtag.js) */}
  91. <Script src="https://www.googletagmanager.com/gtag/js?id=AW-17391954825" strategy="afterInteractive" />
  92. <Script id="google-analytics" strategy="afterInteractive">
  93. {`
  94. window.dataLayer = window.dataLayer || [];
  95. function gtag(){dataLayer.push(arguments);}
  96. gtag('js', new Date());
  97. gtag('config', 'AW-17391954825');
  98. `}
  99. </Script>
  100. <div itemScope itemType="https://schema.org/WebSite">
  101. <link itemProp="url" href={SEO.url} />
  102. <meta itemProp="name" content={SEO.name} />
  103. </div>
  104. <Providers>
  105. <Shell>{children}</Shell>
  106. </Providers>
  107. </body>
  108. </html>
  109. )
  110. }