diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..0732a3f --- /dev/null +++ b/public/favicon.ico @@ -0,0 +1 @@ +data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////3//////////////9/f3//f39//39/f/9/f3//f39////////////////////AAAAAAAAAAAAAAAA////////////////////////////8/Pz//Pz8//z8/P/8/Pz//Pz8////////////////////AAAAAAAAAAAAAAAA////////////////////////////8/Pz//Pz8//z8/P/8/Pz//Pz8////////////////////AAAAAAAAAAAAAAAA////////////////////////////5+fn/+fn5//n5+f/5+fn/+fn5////////////////////AAAAAAAAAAAAAAAA//////3+/v7////////////9/f3//f39//39/f/9/f3//f39////////////////AAAAAAAAAAAAAAAA//////3+/v7////////////9/f3//f39//39/f/9/f3//f39////////////////AAAAAAAAAAAAAAAA//////3+/v7////////////9/f3//f39//39/f/9/f3//f39////////////////AAAAAAAAAAAAAAAA//////3+/v7////////////9/f3//f39//39/f/9/f3//f39////////////////AAAAAAAAAAAAAAAA//////3+/v7////////////9/f3//f39//39/f/9/f3//f39////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA//////////////// diff --git a/public/icon.svg b/public/icon.svg new file mode 100644 index 0000000..b07462c --- /dev/null +++ b/public/icon.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..4cf7f9b --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,75 @@ +{ + "name": "Mini Game AI - AI-Powered Tools for Game Developers", + "short_name": "Mini Game AI", + "description": "Transform your game development workflow with AI-powered tools. Video to frames, image compression, audio processing, texture atlas generation, and more.", + "start_url": "/", + "display": "standalone", + "background_color": "#09090b", + "theme_color": "#3b82f6", + "orientation": "portrait-primary", + "icons": [ + { + "src": "/icon-72x72.png", + "sizes": "72x72", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "/icon-96x96.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "/icon-128x128.png", + "sizes": "128x128", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "/icon-144x144.png", + "sizes": "144x144", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "/icon-152x152.png", + "sizes": "152x152", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "/icon-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "/icon-384x384.png", + "sizes": "384x384", + "type": "image/png", + "purpose": "maskable any" + }, + { + "src": "/icon-512x512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable any" + } + ], + "categories": ["productivity", "utilities", "developer"], + "screenshots": [ + { + "src": "/screenshot-desktop.png", + "sizes": "1280x720", + "type": "image/png", + "form_factor": "wide" + }, + { + "src": "/screenshot-mobile.png", + "sizes": "750x1334", + "type": "image/png", + "form_factor": "narrow" + } + ] +} diff --git a/src/app/(dashboard)/tools/texture-atlas/layout.tsx b/src/app/(dashboard)/tools/texture-atlas/layout.tsx new file mode 100644 index 0000000..8da6b97 --- /dev/null +++ b/src/app/(dashboard)/tools/texture-atlas/layout.tsx @@ -0,0 +1,67 @@ +import type { Metadata } from "next"; +import { headers } from "next/headers"; + +export async function generateMetadata(): Promise { + const headersList = await headers(); + const acceptLanguage = headersList.get("accept-language") || ""; + const lang = acceptLanguage.includes("zh") ? "zh" : "en"; + + const titles = { + en: "Texture Atlas Generator - Create Sprite Sheets Online", + zh: "纹理图集生成器 - 在线创建精灵图", + }; + + const descriptions = { + en: "Generate texture atlases and sprite sheets for game development. Pack multiple sprites into a single texture atlas with JSON data export. All processing happens locally in your browser.", + zh: "为游戏开发生成纹理图集和精灵图。将多个精灵打包到单个纹理图集中,支持导出 JSON 数据。所有处理都在您的浏览器本地进行。", + }; + + const keywords = { + en: [ + "texture atlas", + "sprite sheet", + "game development", + "sprite packer", + "texture packing", + "game assets", + "sprite generator", + "JSON export", + "browser-based", + ], + zh: [ + "纹理图集", + "精灵图", + "游戏开发", + "精灵打包", + "纹理打包", + "游戏资产", + "精灵生成器", + "JSON导出", + "浏览器端", + ], + }; + + return { + title: titles[lang], + description: descriptions[lang], + keywords: keywords[lang], + openGraph: { + title: titles[lang], + description: descriptions[lang], + type: "website", + }, + twitter: { + title: titles[lang], + description: descriptions[lang], + card: "summary_large_image", + }, + }; +} + +export default function TextureAtlasLayout({ + children, +}: { + children: React.ReactNode; +}) { + return children; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index b9ef42d..d0ad2d1 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,28 +1,170 @@ import type { Metadata } from "next"; +import { cookies, headers } from "next/headers"; import "./globals.css"; import { Header } from "@/components/layout/Header"; import { Footer } from "@/components/layout/Footer"; import { cn } from "@/lib/utils"; +import { WebSiteStructuredData, OrganizationStructuredData } from "@/components/seo/StructuredData"; +import { + LOCALE_COOKIE_NAME, + getLocaleFromAcceptLanguage, + type Locale +} from "@/lib/i18n-server"; export const metadata: Metadata = { - title: "Mini Game AI - AI-Powered Tools for Game Developers", + metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL || "https://minigameai.com"), + title: { + default: "Mini Game AI - AI-Powered Tools for Game Developers", + template: "%s | Mini Game AI", + }, description: - "Transform your game development workflow with AI-powered tools. Video to frames, image compression, audio processing, and more.", - keywords: ["game development", "AI tools", "video processing", "image compression", "audio processing"], + "Transform your game development workflow with AI-powered tools. Video to frames, image compression, audio processing, texture atlas generation, and more. All processing happens locally in your browser.", + keywords: [ + "game development", + "AI tools", + "video processing", + "image compression", + "audio processing", + "texture atlas", + "sprite sheet", + "game assets", + "WebP converter", + "PNG optimizer", + "video frames", + "browser-based tools", + "privacy-first", + "no upload", + ], + authors: [{ name: "Mini Game AI", url: "https://minigameai.com" }], + creator: "Mini Game AI", + publisher: "Mini Game AI", + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + "max-video-preview": -1, + "max-image-preview": "large", + "max-snippet": -1, + }, + }, + icons: { + icon: [ + { url: "/icon.svg", type: "image/svg+xml" }, + { url: "/icon-192.png", sizes: "192x192", type: "image/png" }, + { url: "/icon-512.png", sizes: "512x512", type: "image/png" }, + ], + shortcut: "/icon-192.png", + apple: [ + { url: "/apple-touch-icon.png", sizes: "180x180", type: "image/png" }, + ], + }, + manifest: "/manifest.json", + appleWebApp: { + capable: true, + title: "Mini Game AI", + statusBarStyle: "default", + }, + openGraph: { + type: "website", + siteName: "Mini Game AI", + title: "Mini Game AI - AI-Powered Tools for Game Developers", + description: + "Transform your game development workflow with AI-powered tools. Video to frames, image compression, audio processing, texture atlas generation, and more. All processing happens locally in your browser.", + url: "/", + locale: "en_US", + alternateLocale: ["zh_CN"], + images: [ + { + url: "/og-image.png", + width: 1200, + height: 630, + alt: "Mini Game AI - AI-Powered Tools for Game Developers", + }, + ], + }, + twitter: { + card: "summary_large_image", + title: "Mini Game AI - AI-Powered Tools for Game Developers", + description: + "Transform your game development workflow with AI-powered tools. Video to frames, image compression, audio processing, texture atlas generation, and more.", + site: "@minigameai", + creator: "@minigameai", + images: ["/twitter-image.png"], + }, + alternates: { + canonical: "/", + }, + category: "technology", }; -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { + // Detect locale from cookie or Accept-Language header + const cookieStore = await cookies(); + const headersList = await headers(); + + let locale: Locale = "en"; + + // 1. Check cookie first (user's explicit preference) + const cookieLocale = cookieStore.get(LOCALE_COOKIE_NAME)?.value; + if (cookieLocale === "en" || cookieLocale === "zh") { + locale = cookieLocale; + } else { + // 2. Fall back to Accept-Language header + const acceptLanguage = headersList.get("accept-language"); + locale = getLocaleFromAcceptLanguage(acceptLanguage); + } + return ( - + + + + + {/* Inline script to set locale before React hydrates, preventing flash */} +