Spaces:
				
			
			
	
			
			
					
		Running
		
	
	
	
			
			
	
	
	
	
		
		
					
		Running
		
	improve SEO
Browse files- app/[namespace]/[repoId]/page.tsx +18 -0
 - app/layout.tsx +34 -22
 - app/new/page.tsx +9 -0
 - app/sitemap.ts +28 -0
 - components/iframe-detector/index.tsx +39 -0
 - lib/seo.ts +131 -0
 - middleware.ts +18 -1
 - public/robots.txt +17 -0
 
    	
        app/[namespace]/[repoId]/page.tsx
    CHANGED
    
    | 
         @@ -1,4 +1,22 @@ 
     | 
|
| 1 | 
         
             
            import { AppEditor } from "@/components/editor";
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 2 | 
         | 
| 3 | 
         
             
            export default async function ProjectNamespacePage({
         
     | 
| 4 | 
         
             
              params,
         
     | 
| 
         | 
|
| 1 | 
         
             
            import { AppEditor } from "@/components/editor";
         
     | 
| 2 | 
         
            +
            import { generateSEO } from "@/lib/seo";
         
     | 
| 3 | 
         
            +
            import { Metadata } from "next";
         
     | 
| 4 | 
         
            +
             
     | 
| 5 | 
         
            +
            export async function generateMetadata({
         
     | 
| 6 | 
         
            +
              params,
         
     | 
| 7 | 
         
            +
            }: {
         
     | 
| 8 | 
         
            +
              params: Promise<{ namespace: string; repoId: string }>;
         
     | 
| 9 | 
         
            +
            }): Promise<Metadata> {
         
     | 
| 10 | 
         
            +
              const { namespace, repoId } = await params;
         
     | 
| 11 | 
         
            +
             
     | 
| 12 | 
         
            +
              return generateSEO({
         
     | 
| 13 | 
         
            +
                title: `${namespace}/${repoId} - DeepSite Editor`,
         
     | 
| 14 | 
         
            +
                description: `Edit and build ${namespace}/${repoId} with AI-powered tools on DeepSite. Create stunning websites with no code required.`,
         
     | 
| 15 | 
         
            +
                path: `/${namespace}/${repoId}`,
         
     | 
| 16 | 
         
            +
                // Prevent indexing of individual project editor pages if they contain sensitive content
         
     | 
| 17 | 
         
            +
                noIndex: false, // Set to true if you want to keep project pages private
         
     | 
| 18 | 
         
            +
              });
         
     | 
| 19 | 
         
            +
            }
         
     | 
| 20 | 
         | 
| 21 | 
         
             
            export default async function ProjectNamespacePage({
         
     | 
| 22 | 
         
             
              params,
         
     | 
    	
        app/layout.tsx
    CHANGED
    
    | 
         @@ -13,6 +13,7 @@ import AppContext from "@/components/contexts/app-context"; 
     | 
|
| 13 | 
         
             
            import TanstackContext from "@/components/contexts/tanstack-query-context";
         
     | 
| 14 | 
         
             
            import { LoginProvider } from "@/components/contexts/login-context";
         
     | 
| 15 | 
         
             
            import { ProProvider } from "@/components/contexts/pro-context";
         
     | 
| 
         | 
|
| 16 | 
         | 
| 17 | 
         
             
            const inter = Inter({
         
     | 
| 18 | 
         
             
              variable: "--font-inter-sans",
         
     | 
| 
         @@ -26,31 +27,12 @@ const ptSans = PT_Sans({ 
     | 
|
| 26 | 
         
             
            });
         
     | 
| 27 | 
         | 
| 28 | 
         
             
            export const metadata: Metadata = {
         
     | 
| 29 | 
         
            -
               
     | 
| 30 | 
         
            -
              description:
         
     | 
| 31 | 
         
            -
                "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.",
         
     | 
| 32 | 
         
            -
              openGraph: {
         
     | 
| 33 | 
         
             
                title: "DeepSite | Build with AI ✨",
         
     | 
| 34 | 
         
             
                description:
         
     | 
| 35 | 
         
             
                  "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.",
         
     | 
| 36 | 
         
            -
                 
     | 
| 37 | 
         
            -
             
     | 
| 38 | 
         
            -
                images: [
         
     | 
| 39 | 
         
            -
                  {
         
     | 
| 40 | 
         
            -
                    url: "https://deepsite.hf.co/banner.png",
         
     | 
| 41 | 
         
            -
                    width: 1200,
         
     | 
| 42 | 
         
            -
                    height: 630,
         
     | 
| 43 | 
         
            -
                    alt: "DeepSite Open Graph Image",
         
     | 
| 44 | 
         
            -
                  },
         
     | 
| 45 | 
         
            -
                ],
         
     | 
| 46 | 
         
            -
              },
         
     | 
| 47 | 
         
            -
              twitter: {
         
     | 
| 48 | 
         
            -
                card: "summary_large_image",
         
     | 
| 49 | 
         
            -
                title: "DeepSite | Build with AI ✨",
         
     | 
| 50 | 
         
            -
                description:
         
     | 
| 51 | 
         
            -
                  "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.",
         
     | 
| 52 | 
         
            -
                images: ["https://deepsite.hf.co/banner.png"],
         
     | 
| 53 | 
         
            -
              },
         
     | 
| 54 | 
         
             
              appleWebApp: {
         
     | 
| 55 | 
         
             
                capable: true,
         
     | 
| 56 | 
         
             
                title: "DeepSite",
         
     | 
| 
         @@ -61,6 +43,9 @@ export const metadata: Metadata = { 
     | 
|
| 61 | 
         
             
                shortcut: "/logo.svg",
         
     | 
| 62 | 
         
             
                apple: "/logo.svg",
         
     | 
| 63 | 
         
             
              },
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 64 | 
         
             
            };
         
     | 
| 65 | 
         | 
| 66 | 
         
             
            export const viewport: Viewport = {
         
     | 
| 
         @@ -91,8 +76,35 @@ export default async function RootLayout({ 
     | 
|
| 91 | 
         
             
              children: React.ReactNode;
         
     | 
| 92 | 
         
             
            }>) {
         
     | 
| 93 | 
         
             
              const data = await getMe();
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 94 | 
         
             
              return (
         
     | 
| 95 | 
         
             
                <html lang="en">
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 96 | 
         
             
                  <Script
         
     | 
| 97 | 
         
             
                    defer
         
     | 
| 98 | 
         
             
                    data-domain="deepsite.hf.co"
         
     | 
| 
         | 
|
| 13 | 
         
             
            import TanstackContext from "@/components/contexts/tanstack-query-context";
         
     | 
| 14 | 
         
             
            import { LoginProvider } from "@/components/contexts/login-context";
         
     | 
| 15 | 
         
             
            import { ProProvider } from "@/components/contexts/pro-context";
         
     | 
| 16 | 
         
            +
            import { generateSEO, generateStructuredData } from "@/lib/seo";
         
     | 
| 17 | 
         | 
| 18 | 
         
             
            const inter = Inter({
         
     | 
| 19 | 
         
             
              variable: "--font-inter-sans",
         
     | 
| 
         | 
|
| 27 | 
         
             
            });
         
     | 
| 28 | 
         | 
| 29 | 
         
             
            export const metadata: Metadata = {
         
     | 
| 30 | 
         
            +
              ...generateSEO({
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 31 | 
         
             
                title: "DeepSite | Build with AI ✨",
         
     | 
| 32 | 
         
             
                description:
         
     | 
| 33 | 
         
             
                  "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.",
         
     | 
| 34 | 
         
            +
                path: "/",
         
     | 
| 35 | 
         
            +
              }),
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 36 | 
         
             
              appleWebApp: {
         
     | 
| 37 | 
         
             
                capable: true,
         
     | 
| 38 | 
         
             
                title: "DeepSite",
         
     | 
| 
         | 
|
| 43 | 
         
             
                shortcut: "/logo.svg",
         
     | 
| 44 | 
         
             
                apple: "/logo.svg",
         
     | 
| 45 | 
         
             
              },
         
     | 
| 46 | 
         
            +
              verification: {
         
     | 
| 47 | 
         
            +
                google: process.env.GOOGLE_SITE_VERIFICATION,
         
     | 
| 48 | 
         
            +
              },
         
     | 
| 49 | 
         
             
            };
         
     | 
| 50 | 
         | 
| 51 | 
         
             
            export const viewport: Viewport = {
         
     | 
| 
         | 
|
| 76 | 
         
             
              children: React.ReactNode;
         
     | 
| 77 | 
         
             
            }>) {
         
     | 
| 78 | 
         
             
              const data = await getMe();
         
     | 
| 79 | 
         
            +
             
     | 
| 80 | 
         
            +
              // Generate structured data
         
     | 
| 81 | 
         
            +
              const structuredData = generateStructuredData("WebApplication", {
         
     | 
| 82 | 
         
            +
                name: "DeepSite",
         
     | 
| 83 | 
         
            +
                description: "Build websites with AI, no code required",
         
     | 
| 84 | 
         
            +
                url: "https://deepsite.hf.co",
         
     | 
| 85 | 
         
            +
              });
         
     | 
| 86 | 
         
            +
             
     | 
| 87 | 
         
            +
              const organizationData = generateStructuredData("Organization", {
         
     | 
| 88 | 
         
            +
                name: "DeepSite",
         
     | 
| 89 | 
         
            +
                url: "https://deepsite.hf.co",
         
     | 
| 90 | 
         
            +
              });
         
     | 
| 91 | 
         
            +
             
     | 
| 92 | 
         
             
              return (
         
     | 
| 93 | 
         
             
                <html lang="en">
         
     | 
| 94 | 
         
            +
                  <head>
         
     | 
| 95 | 
         
            +
                    <script
         
     | 
| 96 | 
         
            +
                      type="application/ld+json"
         
     | 
| 97 | 
         
            +
                      dangerouslySetInnerHTML={{
         
     | 
| 98 | 
         
            +
                        __html: JSON.stringify(structuredData),
         
     | 
| 99 | 
         
            +
                      }}
         
     | 
| 100 | 
         
            +
                    />
         
     | 
| 101 | 
         
            +
                    <script
         
     | 
| 102 | 
         
            +
                      type="application/ld+json"
         
     | 
| 103 | 
         
            +
                      dangerouslySetInnerHTML={{
         
     | 
| 104 | 
         
            +
                        __html: JSON.stringify(organizationData),
         
     | 
| 105 | 
         
            +
                      }}
         
     | 
| 106 | 
         
            +
                    />
         
     | 
| 107 | 
         
            +
                  </head>
         
     | 
| 108 | 
         
             
                  <Script
         
     | 
| 109 | 
         
             
                    defer
         
     | 
| 110 | 
         
             
                    data-domain="deepsite.hf.co"
         
     | 
    	
        app/new/page.tsx
    CHANGED
    
    | 
         @@ -1,4 +1,13 @@ 
     | 
|
| 1 | 
         
             
            import { AppEditor } from "@/components/editor";
         
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 2 | 
         | 
| 3 | 
         
             
            export default function NewProjectPage() {
         
     | 
| 4 | 
         
             
              return <AppEditor isNew />;
         
     | 
| 
         | 
|
| 1 | 
         
             
            import { AppEditor } from "@/components/editor";
         
     | 
| 2 | 
         
            +
            import { Metadata } from "next";
         
     | 
| 3 | 
         
            +
            import { generateSEO } from "@/lib/seo";
         
     | 
| 4 | 
         
            +
             
     | 
| 5 | 
         
            +
            export const metadata: Metadata = generateSEO({
         
     | 
| 6 | 
         
            +
              title: "Create New Project - DeepSite",
         
     | 
| 7 | 
         
            +
              description:
         
     | 
| 8 | 
         
            +
                "Start building your next website with AI. Create a new project on DeepSite and experience the power of AI-driven web development.",
         
     | 
| 9 | 
         
            +
              path: "/new",
         
     | 
| 10 | 
         
            +
            });
         
     | 
| 11 | 
         | 
| 12 | 
         
             
            export default function NewProjectPage() {
         
     | 
| 13 | 
         
             
              return <AppEditor isNew />;
         
     | 
    	
        app/sitemap.ts
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
| 
         | 
|
| 1 | 
         
            +
            import { MetadataRoute } from 'next';
         
     | 
| 2 | 
         
            +
             
     | 
| 3 | 
         
            +
            export default function sitemap(): MetadataRoute.Sitemap {
         
     | 
| 4 | 
         
            +
              const baseUrl = 'https://deepsite.hf.co';
         
     | 
| 5 | 
         
            +
              
         
     | 
| 6 | 
         
            +
              return [
         
     | 
| 7 | 
         
            +
                {
         
     | 
| 8 | 
         
            +
                  url: baseUrl,
         
     | 
| 9 | 
         
            +
                  lastModified: new Date(),
         
     | 
| 10 | 
         
            +
                  changeFrequency: 'daily',
         
     | 
| 11 | 
         
            +
                  priority: 1,
         
     | 
| 12 | 
         
            +
                },
         
     | 
| 13 | 
         
            +
                {
         
     | 
| 14 | 
         
            +
                  url: `${baseUrl}/new`,
         
     | 
| 15 | 
         
            +
                  lastModified: new Date(),
         
     | 
| 16 | 
         
            +
                  changeFrequency: 'weekly',
         
     | 
| 17 | 
         
            +
                  priority: 0.8,
         
     | 
| 18 | 
         
            +
                },
         
     | 
| 19 | 
         
            +
                {
         
     | 
| 20 | 
         
            +
                  url: `${baseUrl}/auth`,
         
     | 
| 21 | 
         
            +
                  lastModified: new Date(),
         
     | 
| 22 | 
         
            +
                  changeFrequency: 'monthly',
         
     | 
| 23 | 
         
            +
                  priority: 0.5,
         
     | 
| 24 | 
         
            +
                },
         
     | 
| 25 | 
         
            +
                // Note: Dynamic project routes will be handled by Next.js automatically
         
     | 
| 26 | 
         
            +
                // but you can add specific high-priority project pages here if needed
         
     | 
| 27 | 
         
            +
              ];
         
     | 
| 28 | 
         
            +
            }
         
     | 
    	
        components/iframe-detector/index.tsx
    CHANGED
    
    | 
         @@ -41,6 +41,42 @@ export default function IframeDetector() { 
     | 
|
| 41 | 
         
             
                  }
         
     | 
| 42 | 
         
             
                };
         
     | 
| 43 | 
         | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 44 | 
         
             
                // Check if we're in an iframe from a non-allowed domain
         
     | 
| 45 | 
         
             
                const shouldShowWarning = () => {
         
     | 
| 46 | 
         
             
                  if (!isInIframe() && !isEmbedded()) {
         
     | 
| 
         @@ -65,6 +101,9 @@ export default function IframeDetector() { 
     | 
|
| 65 | 
         
             
                  }
         
     | 
| 66 | 
         
             
                };
         
     | 
| 67 | 
         | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 68 | 
         
             
                if (shouldShowWarning()) {
         
     | 
| 69 | 
         
             
                  // Show warning modal instead of redirecting immediately
         
     | 
| 70 | 
         
             
                  setShowWarning(true);
         
     | 
| 
         | 
|
| 41 | 
         
             
                  }
         
     | 
| 42 | 
         
             
                };
         
     | 
| 43 | 
         | 
| 44 | 
         
            +
                // SEO: Add canonical URL meta tag when in iframe
         
     | 
| 45 | 
         
            +
                const addCanonicalUrl = () => {
         
     | 
| 46 | 
         
            +
                  // Remove existing canonical link if present
         
     | 
| 47 | 
         
            +
                  const existingCanonical = document.querySelector('link[rel="canonical"]');
         
     | 
| 48 | 
         
            +
                  if (existingCanonical) {
         
     | 
| 49 | 
         
            +
                    existingCanonical.remove();
         
     | 
| 50 | 
         
            +
                  }
         
     | 
| 51 | 
         
            +
             
     | 
| 52 | 
         
            +
                  // Add canonical URL pointing to the standalone version
         
     | 
| 53 | 
         
            +
                  const canonical = document.createElement("link");
         
     | 
| 54 | 
         
            +
                  canonical.rel = "canonical";
         
     | 
| 55 | 
         
            +
                  canonical.href = window.location.href;
         
     | 
| 56 | 
         
            +
                  document.head.appendChild(canonical);
         
     | 
| 57 | 
         
            +
             
     | 
| 58 | 
         
            +
                  // Add meta tag to indicate this page should not be indexed when in iframe from unauthorized domains
         
     | 
| 59 | 
         
            +
                  if (isInIframe() || isEmbedded()) {
         
     | 
| 60 | 
         
            +
                    try {
         
     | 
| 61 | 
         
            +
                      const parentHostname = document.referrer
         
     | 
| 62 | 
         
            +
                        ? new URL(document.referrer).hostname
         
     | 
| 63 | 
         
            +
                        : null;
         
     | 
| 64 | 
         
            +
                      if (parentHostname && !isAllowedDomain(parentHostname)) {
         
     | 
| 65 | 
         
            +
                        // Add noindex meta tag when embedded in unauthorized domains
         
     | 
| 66 | 
         
            +
                        const noIndexMeta = document.createElement("meta");
         
     | 
| 67 | 
         
            +
                        noIndexMeta.name = "robots";
         
     | 
| 68 | 
         
            +
                        noIndexMeta.content = "noindex, nofollow";
         
     | 
| 69 | 
         
            +
                        document.head.appendChild(noIndexMeta);
         
     | 
| 70 | 
         
            +
                      }
         
     | 
| 71 | 
         
            +
                    } catch (error) {
         
     | 
| 72 | 
         
            +
                      // Silently handle cross-origin errors
         
     | 
| 73 | 
         
            +
                      console.debug(
         
     | 
| 74 | 
         
            +
                        "SEO: Could not determine parent domain for iframe indexing rules"
         
     | 
| 75 | 
         
            +
                      );
         
     | 
| 76 | 
         
            +
                    }
         
     | 
| 77 | 
         
            +
                  }
         
     | 
| 78 | 
         
            +
                };
         
     | 
| 79 | 
         
            +
             
     | 
| 80 | 
         
             
                // Check if we're in an iframe from a non-allowed domain
         
     | 
| 81 | 
         
             
                const shouldShowWarning = () => {
         
     | 
| 82 | 
         
             
                  if (!isInIframe() && !isEmbedded()) {
         
     | 
| 
         | 
|
| 101 | 
         
             
                  }
         
     | 
| 102 | 
         
             
                };
         
     | 
| 103 | 
         | 
| 104 | 
         
            +
                // Always add canonical URL for SEO, regardless of iframe status
         
     | 
| 105 | 
         
            +
                addCanonicalUrl();
         
     | 
| 106 | 
         
            +
             
     | 
| 107 | 
         
             
                if (shouldShowWarning()) {
         
     | 
| 108 | 
         
             
                  // Show warning modal instead of redirecting immediately
         
     | 
| 109 | 
         
             
                  setShowWarning(true);
         
     | 
    	
        lib/seo.ts
    ADDED
    
    | 
         @@ -0,0 +1,131 @@ 
     | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
| 
         | 
|
| 1 | 
         
            +
            import { Metadata } from "next";
         
     | 
| 2 | 
         
            +
             
     | 
| 3 | 
         
            +
            interface SEOParams {
         
     | 
| 4 | 
         
            +
              title?: string;
         
     | 
| 5 | 
         
            +
              description?: string;
         
     | 
| 6 | 
         
            +
              path?: string;
         
     | 
| 7 | 
         
            +
              image?: string;
         
     | 
| 8 | 
         
            +
              noIndex?: boolean;
         
     | 
| 9 | 
         
            +
              canonical?: string;
         
     | 
| 10 | 
         
            +
            }
         
     | 
| 11 | 
         
            +
             
     | 
| 12 | 
         
            +
            export function generateSEO({
         
     | 
| 13 | 
         
            +
              title = "DeepSite | Build with AI ✨",
         
     | 
| 14 | 
         
            +
              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.",
         
     | 
| 15 | 
         
            +
              path = "",
         
     | 
| 16 | 
         
            +
              image = "/banner.png",
         
     | 
| 17 | 
         
            +
              noIndex = false,
         
     | 
| 18 | 
         
            +
              canonical,
         
     | 
| 19 | 
         
            +
            }: SEOParams = {}): Metadata {
         
     | 
| 20 | 
         
            +
              const baseUrl = "https://deepsite.hf.co";
         
     | 
| 21 | 
         
            +
              const fullUrl = `${baseUrl}${path}`;
         
     | 
| 22 | 
         
            +
              const canonicalUrl = canonical || fullUrl;
         
     | 
| 23 | 
         
            +
              
         
     | 
| 24 | 
         
            +
              return {
         
     | 
| 25 | 
         
            +
                title,
         
     | 
| 26 | 
         
            +
                description,
         
     | 
| 27 | 
         
            +
                alternates: {
         
     | 
| 28 | 
         
            +
                  canonical: canonicalUrl,
         
     | 
| 29 | 
         
            +
                },
         
     | 
| 30 | 
         
            +
                robots: noIndex 
         
     | 
| 31 | 
         
            +
                  ? { 
         
     | 
| 32 | 
         
            +
                      index: false, 
         
     | 
| 33 | 
         
            +
                      follow: false,
         
     | 
| 34 | 
         
            +
                      googleBot: {
         
     | 
| 35 | 
         
            +
                        index: false,
         
     | 
| 36 | 
         
            +
                        follow: false,
         
     | 
| 37 | 
         
            +
                        'max-video-preview': -1,
         
     | 
| 38 | 
         
            +
                        'max-image-preview': 'large',
         
     | 
| 39 | 
         
            +
                        'max-snippet': -1,
         
     | 
| 40 | 
         
            +
                      }
         
     | 
| 41 | 
         
            +
                    }
         
     | 
| 42 | 
         
            +
                  : {
         
     | 
| 43 | 
         
            +
                      index: true,
         
     | 
| 44 | 
         
            +
                      follow: true,
         
     | 
| 45 | 
         
            +
                      googleBot: {
         
     | 
| 46 | 
         
            +
                        index: true,
         
     | 
| 47 | 
         
            +
                        follow: true,
         
     | 
| 48 | 
         
            +
                        'max-video-preview': -1,
         
     | 
| 49 | 
         
            +
                        'max-image-preview': 'large',
         
     | 
| 50 | 
         
            +
                        'max-snippet': -1,
         
     | 
| 51 | 
         
            +
                      }
         
     | 
| 52 | 
         
            +
                    },
         
     | 
| 53 | 
         
            +
                openGraph: {
         
     | 
| 54 | 
         
            +
                  title,
         
     | 
| 55 | 
         
            +
                  description,
         
     | 
| 56 | 
         
            +
                  url: canonicalUrl,
         
     | 
| 57 | 
         
            +
                  siteName: "DeepSite",
         
     | 
| 58 | 
         
            +
                  images: [
         
     | 
| 59 | 
         
            +
                    {
         
     | 
| 60 | 
         
            +
                      url: `${baseUrl}${image}`,
         
     | 
| 61 | 
         
            +
                      width: 1200,
         
     | 
| 62 | 
         
            +
                      height: 630,
         
     | 
| 63 | 
         
            +
                      alt: `${title} - DeepSite`,
         
     | 
| 64 | 
         
            +
                    },
         
     | 
| 65 | 
         
            +
                  ],
         
     | 
| 66 | 
         
            +
                  locale: "en_US",
         
     | 
| 67 | 
         
            +
                  type: "website",
         
     | 
| 68 | 
         
            +
                },
         
     | 
| 69 | 
         
            +
                twitter: {
         
     | 
| 70 | 
         
            +
                  card: "summary_large_image",
         
     | 
| 71 | 
         
            +
                  title,
         
     | 
| 72 | 
         
            +
                  description,
         
     | 
| 73 | 
         
            +
                  images: [`${baseUrl}${image}`],
         
     | 
| 74 | 
         
            +
                  creator: "@deepsite",
         
     | 
| 75 | 
         
            +
                },
         
     | 
| 76 | 
         
            +
                other: {
         
     | 
| 77 | 
         
            +
                  // Prevent iframe embedding from unauthorized domains
         
     | 
| 78 | 
         
            +
                  'X-Frame-Options': 'SAMEORIGIN',
         
     | 
| 79 | 
         
            +
                  // Control how the page appears when shared
         
     | 
| 80 | 
         
            +
                  'og:image:secure_url': `${baseUrl}${image}`,
         
     | 
| 81 | 
         
            +
                  // Help search engines understand the primary URL
         
     | 
| 82 | 
         
            +
                  'rel': 'canonical',
         
     | 
| 83 | 
         
            +
                },
         
     | 
| 84 | 
         
            +
              };
         
     | 
| 85 | 
         
            +
            }
         
     | 
| 86 | 
         
            +
             
     | 
| 87 | 
         
            +
            export function generateStructuredData(type: 'WebApplication' | 'Organization' | 'Article', data: any) {
         
     | 
| 88 | 
         
            +
              const baseStructuredData = {
         
     | 
| 89 | 
         
            +
                '@context': 'https://schema.org',
         
     | 
| 90 | 
         
            +
                '@type': type,
         
     | 
| 91 | 
         
            +
              };
         
     | 
| 92 | 
         
            +
             
     | 
| 93 | 
         
            +
              switch (type) {
         
     | 
| 94 | 
         
            +
                case 'WebApplication':
         
     | 
| 95 | 
         
            +
                  return {
         
     | 
| 96 | 
         
            +
                    ...baseStructuredData,
         
     | 
| 97 | 
         
            +
                    name: 'DeepSite',
         
     | 
| 98 | 
         
            +
                    description: 'Build websites with AI, no code required',
         
     | 
| 99 | 
         
            +
                    url: 'https://deepsite.hf.co',
         
     | 
| 100 | 
         
            +
                    applicationCategory: 'DeveloperApplication',
         
     | 
| 101 | 
         
            +
                    operatingSystem: 'Web',
         
     | 
| 102 | 
         
            +
                    offers: {
         
     | 
| 103 | 
         
            +
                      '@type': 'Offer',
         
     | 
| 104 | 
         
            +
                      price: '0',
         
     | 
| 105 | 
         
            +
                      priceCurrency: 'USD',
         
     | 
| 106 | 
         
            +
                    },
         
     | 
| 107 | 
         
            +
                    creator: {
         
     | 
| 108 | 
         
            +
                      '@type': 'Organization',
         
     | 
| 109 | 
         
            +
                      name: 'DeepSite',
         
     | 
| 110 | 
         
            +
                      url: 'https://deepsite.hf.co',
         
     | 
| 111 | 
         
            +
                    },
         
     | 
| 112 | 
         
            +
                    ...data,
         
     | 
| 113 | 
         
            +
                  };
         
     | 
| 114 | 
         
            +
                
         
     | 
| 115 | 
         
            +
                case 'Organization':
         
     | 
| 116 | 
         
            +
                  return {
         
     | 
| 117 | 
         
            +
                    ...baseStructuredData,
         
     | 
| 118 | 
         
            +
                    name: 'DeepSite',
         
     | 
| 119 | 
         
            +
                    url: 'https://deepsite.hf.co',
         
     | 
| 120 | 
         
            +
                    logo: 'https://deepsite.hf.co/logo.svg',
         
     | 
| 121 | 
         
            +
                    description: 'AI-powered web development platform',
         
     | 
| 122 | 
         
            +
                    sameAs: [
         
     | 
| 123 | 
         
            +
                      // Add social media links here if available
         
     | 
| 124 | 
         
            +
                    ],
         
     | 
| 125 | 
         
            +
                    ...data,
         
     | 
| 126 | 
         
            +
                  };
         
     | 
| 127 | 
         
            +
                
         
     | 
| 128 | 
         
            +
                default:
         
     | 
| 129 | 
         
            +
                  return { ...baseStructuredData, ...data };
         
     | 
| 130 | 
         
            +
              }
         
     | 
| 131 | 
         
            +
            }
         
     | 
    	
        middleware.ts
    CHANGED
    
    | 
         @@ -4,7 +4,24 @@ import type { NextRequest } from "next/server"; 
     | 
|
| 4 | 
         
             
            export function middleware(request: NextRequest) {
         
     | 
| 5 | 
         
             
              const headers = new Headers(request.headers);
         
     | 
| 6 | 
         
             
              headers.set("x-current-host", request.nextUrl.host);
         
     | 
| 7 | 
         
            -
               
     | 
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 8 | 
         
             
            }
         
     | 
| 9 | 
         | 
| 10 | 
         
             
            export const config = {
         
     | 
| 
         | 
|
| 4 | 
         
             
            export function middleware(request: NextRequest) {
         
     | 
| 5 | 
         
             
              const headers = new Headers(request.headers);
         
     | 
| 6 | 
         
             
              headers.set("x-current-host", request.nextUrl.host);
         
     | 
| 7 | 
         
            +
              
         
     | 
| 8 | 
         
            +
              // Create response with headers
         
     | 
| 9 | 
         
            +
              const response = NextResponse.next({ headers });
         
     | 
| 10 | 
         
            +
              
         
     | 
| 11 | 
         
            +
              // Add SEO and security headers
         
     | 
| 12 | 
         
            +
              response.headers.set('X-Frame-Options', 'SAMEORIGIN');
         
     | 
| 13 | 
         
            +
              response.headers.set('X-Content-Type-Options', 'nosniff');
         
     | 
| 14 | 
         
            +
              response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
         
     | 
| 15 | 
         
            +
              
         
     | 
| 16 | 
         
            +
              // Add cache control for better performance
         
     | 
| 17 | 
         
            +
              if (request.nextUrl.pathname.startsWith('/_next/static')) {
         
     | 
| 18 | 
         
            +
                response.headers.set('Cache-Control', 'public, max-age=31536000, immutable');
         
     | 
| 19 | 
         
            +
              }
         
     | 
| 20 | 
         
            +
              
         
     | 
| 21 | 
         
            +
              // Add canonical URL headers for programmatic access
         
     | 
| 22 | 
         
            +
              response.headers.set('X-Canonical-URL', `https://deepsite.hf.co${request.nextUrl.pathname}`);
         
     | 
| 23 | 
         
            +
              
         
     | 
| 24 | 
         
            +
              return response;
         
     | 
| 25 | 
         
             
            }
         
     | 
| 26 | 
         | 
| 27 | 
         
             
            export const config = {
         
     | 
    	
        public/robots.txt
    ADDED
    
    | 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
|
| 
         | 
| 
         | 
|
| 1 | 
         
            +
            User-agent: *
         
     | 
| 2 | 
         
            +
            Allow: /
         
     | 
| 3 | 
         
            +
             
     | 
| 4 | 
         
            +
            # Block access to API routes and private areas
         
     | 
| 5 | 
         
            +
            Disallow: /api/
         
     | 
| 6 | 
         
            +
            Disallow: /auth/
         
     | 
| 7 | 
         
            +
            Disallow: /_next/
         
     | 
| 8 | 
         
            +
            Disallow: /assets/
         
     | 
| 9 | 
         
            +
             
     | 
| 10 | 
         
            +
            # Allow specific public API endpoints if needed
         
     | 
| 11 | 
         
            +
            Allow: /api/public/
         
     | 
| 12 | 
         
            +
             
     | 
| 13 | 
         
            +
            # Sitemap location
         
     | 
| 14 | 
         
            +
            Sitemap: https://deepsite.hf.co/sitemap.xml
         
     | 
| 15 | 
         
            +
             
     | 
| 16 | 
         
            +
            # Crawl-delay for respectful crawling
         
     | 
| 17 | 
         
            +
            Crawl-delay: 1
         
     |