enzostvs HF Staff commited on
Commit
279aea8
·
1 Parent(s): 9f255de

meta data

Browse files
Files changed (2) hide show
  1. app/layout.tsx +53 -8
  2. lib/seo.ts +133 -0
app/layout.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import type { Metadata } from "next";
2
  import { Geist, Geist_Mono } from "next/font/google";
3
  import { NextStepProvider } from "nextstepjs";
4
 
@@ -7,6 +7,8 @@ import { ThemeProvider } from "@/components/providers/theme";
7
  import { AuthProvider } from "@/components/providers/session";
8
  import { Toaster } from "@/components/ui/sonner";
9
  import { ReactQueryProvider } from "@/components/providers/react-query";
 
 
10
 
11
  const geistSans = Geist({
12
  variable: "--font-geist-sans",
@@ -19,30 +21,73 @@ const geistMono = Geist_Mono({
19
  });
20
 
21
  export const metadata: Metadata = {
22
- title: "Build your next application | DeepSite",
23
- description:
24
- "Build your next application with ease and speed by using AI Vibe Coding.",
 
 
 
 
 
 
 
 
25
  icons: {
26
  icon: "/logo.svg",
27
  shortcut: "/logo.svg",
28
  apple: "/logo.svg",
29
- other: {
30
- rel: "icon",
31
- url: "/logo.svg",
32
- },
33
  },
 
 
 
 
 
 
 
 
 
34
  };
35
 
 
 
36
  export default function RootLayout({
37
  children,
38
  }: Readonly<{
39
  children: React.ReactNode;
40
  }>) {
 
 
 
 
 
 
 
 
 
 
 
41
  return (
42
  <html lang="en" suppressHydrationWarning>
43
  <body
44
  className={`${geistSans.variable} ${geistMono.variable} antialiased`}
45
  >
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  <Toaster richColors />
47
  <AuthProvider>
48
  <ReactQueryProvider>
 
1
+ import type { Metadata, Viewport } from "next";
2
  import { Geist, Geist_Mono } from "next/font/google";
3
  import { NextStepProvider } from "nextstepjs";
4
 
 
7
  import { AuthProvider } from "@/components/providers/session";
8
  import { Toaster } from "@/components/ui/sonner";
9
  import { ReactQueryProvider } from "@/components/providers/react-query";
10
+ import { generateSEO, generateStructuredData } from "@/lib/seo";
11
+ import Script from "next/script";
12
 
13
  const geistSans = Geist({
14
  variable: "--font-geist-sans",
 
21
  });
22
 
23
  export const metadata: Metadata = {
24
+ ...generateSEO({
25
+ title: "DeepSite | Build with AI ✨",
26
+ description:
27
+ "DeepSite is a web development tool that helps you build websites with AI, no code required. Let's deploy your website with DeepSite and enjoy the magic of AI.",
28
+ path: "/",
29
+ }),
30
+ appleWebApp: {
31
+ capable: true,
32
+ title: "DeepSite",
33
+ statusBarStyle: "black-translucent",
34
+ },
35
  icons: {
36
  icon: "/logo.svg",
37
  shortcut: "/logo.svg",
38
  apple: "/logo.svg",
 
 
 
 
39
  },
40
+ verification: {
41
+ google: process.env.GOOGLE_SITE_VERIFICATION,
42
+ },
43
+ };
44
+
45
+ export const viewport: Viewport = {
46
+ initialScale: 1,
47
+ maximumScale: 1,
48
+ themeColor: "#4f46e5",
49
  };
50
 
51
+ // todo add iframe detector, to dont allow people embedding the app in iframes.
52
+
53
  export default function RootLayout({
54
  children,
55
  }: Readonly<{
56
  children: React.ReactNode;
57
  }>) {
58
+ const structuredData = generateStructuredData("WebApplication", {
59
+ name: "DeepSite",
60
+ description: "Build websites with AI, no code required",
61
+ url: "https://huggingface.co/deepsite",
62
+ });
63
+
64
+ const organizationData = generateStructuredData("Organization", {
65
+ name: "DeepSite",
66
+ url: "https://huggingface.co/deepsite",
67
+ });
68
+
69
  return (
70
  <html lang="en" suppressHydrationWarning>
71
  <body
72
  className={`${geistSans.variable} ${geistMono.variable} antialiased`}
73
  >
74
+ <script
75
+ type="application/ld+json"
76
+ dangerouslySetInnerHTML={{
77
+ __html: JSON.stringify(structuredData),
78
+ }}
79
+ />
80
+ <script
81
+ type="application/ld+json"
82
+ dangerouslySetInnerHTML={{
83
+ __html: JSON.stringify(organizationData),
84
+ }}
85
+ />
86
+ <Script
87
+ defer
88
+ data-domain="deepsite.hf.co"
89
+ src="https://plausible.io/js/script.js"
90
+ />
91
  <Toaster richColors />
92
  <AuthProvider>
93
  <ReactQueryProvider>
lib/seo.ts ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Metadata } from "next";
3
+
4
+ interface SEOParams {
5
+ title?: string;
6
+ description?: string;
7
+ path?: string;
8
+ image?: string;
9
+ noIndex?: boolean;
10
+ canonical?: string;
11
+ }
12
+
13
+ export function generateSEO({
14
+ title = "DeepSite | Build with AI ✨",
15
+ description = "DeepSite is a web development tool that helps you build websites with AI, no code required. Let's deploy your website with DeepSite and enjoy the magic of AI.",
16
+ path = "",
17
+ image = "/banner.png",
18
+ noIndex = false,
19
+ canonical,
20
+ }: SEOParams = {}): Metadata {
21
+ const baseUrl = "https://huggingface.co/deepsite";
22
+ const fullUrl = `${baseUrl}${path}`;
23
+ const canonicalUrl = canonical || fullUrl;
24
+
25
+ return {
26
+ title,
27
+ description,
28
+ alternates: {
29
+ canonical: canonicalUrl,
30
+ },
31
+ robots: noIndex
32
+ ? {
33
+ index: false,
34
+ follow: false,
35
+ googleBot: {
36
+ index: false,
37
+ follow: false,
38
+ "max-video-preview": -1,
39
+ "max-image-preview": "large",
40
+ "max-snippet": -1,
41
+ },
42
+ }
43
+ : {
44
+ index: true,
45
+ follow: true,
46
+ googleBot: {
47
+ index: true,
48
+ follow: true,
49
+ "max-video-preview": -1,
50
+ "max-image-preview": "large",
51
+ "max-snippet": -1,
52
+ },
53
+ },
54
+ openGraph: {
55
+ title,
56
+ description,
57
+ url: canonicalUrl,
58
+ siteName: "DeepSite",
59
+ images: [
60
+ {
61
+ url: `${baseUrl}${image}`,
62
+ width: 1200,
63
+ height: 630,
64
+ alt: `${title} - DeepSite`,
65
+ },
66
+ ],
67
+ locale: "en_US",
68
+ type: "website",
69
+ },
70
+ twitter: {
71
+ card: "summary_large_image",
72
+ title,
73
+ description,
74
+ images: [`${baseUrl}${image}`],
75
+ creator: "@deepsite",
76
+ },
77
+ other: {
78
+ // Control how the page appears when shared
79
+ "og:image:secure_url": `${baseUrl}${image}`,
80
+ // Help search engines understand the primary URL
81
+ rel: "canonical",
82
+ },
83
+ };
84
+ }
85
+
86
+ export function generateStructuredData(
87
+ type: "WebApplication" | "Organization" | "Article",
88
+ data: any
89
+ ) {
90
+ const baseStructuredData = {
91
+ "@context": "https://schema.org",
92
+ "@type": type,
93
+ };
94
+
95
+ switch (type) {
96
+ case "WebApplication":
97
+ return {
98
+ ...baseStructuredData,
99
+ name: "DeepSite",
100
+ description: "Build websites with AI, no code required",
101
+ url: "https://huggingface.co/deepsite",
102
+ applicationCategory: "DeveloperApplication",
103
+ operatingSystem: "Web",
104
+ offers: {
105
+ "@type": "Offer",
106
+ price: "0",
107
+ priceCurrency: "USD",
108
+ },
109
+ creator: {
110
+ "@type": "Organization",
111
+ name: "DeepSite",
112
+ url: "https://huggingface.co/deepsite",
113
+ },
114
+ ...data,
115
+ };
116
+
117
+ case "Organization":
118
+ return {
119
+ ...baseStructuredData,
120
+ name: "DeepSite",
121
+ url: "https://huggingface.co/deepsite",
122
+ logo: "https://huggingface.co/deepsite/logo.svg",
123
+ description: "AI-powered web development platform",
124
+ sameAs: [
125
+ // Add social media links here if available
126
+ ],
127
+ ...data,
128
+ };
129
+
130
+ default:
131
+ return { ...baseStructuredData, ...data };
132
+ }
133
+ }