diff --git a/apps/web/src/app/(home)/page.tsx b/apps/web/src/app/(home)/page.tsx
index c5f003d..318a443 100644
--- a/apps/web/src/app/(home)/page.tsx
+++ b/apps/web/src/app/(home)/page.tsx
@@ -1,8 +1,51 @@
import Link from 'next/link';
+import type { Metadata } from 'next';
import { CodeBlock } from '@/components/code-block';
import { CtaCard } from '@/components/cta-card';
import { Footer } from '@/components/footer';
+export const metadata: Metadata = {
+ title: '@deessejs/errors — Error Handling, Reimagined',
+ description:
+ '@deessejs/errors is a TypeScript library bringing Python-inspired error handling to JavaScript. Exception chaining, hierarchical inheritance, message templates, and rich error semantics through a function-based API.',
+ keywords: [
+ 'typescript error handling',
+ 'exception chaining typescript',
+ 'python-style errors javascript',
+ 'error factory typescript',
+ 'structured errors typescript',
+ 'hierarchical error inheritance',
+ ],
+ openGraph: {
+ type: 'website',
+ locale: 'en_US',
+ url: 'https://errors.deessejs.com',
+ siteName: '@deessejs/errors',
+ title: '@deessejs/errors — Error Handling, Reimagined',
+ description:
+ 'A TypeScript library bringing Python-inspired error handling to JavaScript. Exception chaining, hierarchical inheritance, and rich error semantics.',
+ images: [
+ {
+ url: 'https://errors.deessejs.com/og/home.png',
+ width: 1200,
+ height: 630,
+ alt: '@deessejs/errors — TypeScript Error Handling Library',
+ },
+ ],
+ },
+ twitter: {
+ card: 'summary_large_image',
+ title: '@deessejs/errors — Error Handling, Reimagined',
+ description:
+ 'A TypeScript library bringing Python-inspired error handling to JavaScript.',
+ images: ['https://errors.deessejs.com/og/home.png'],
+ creator: '@nesalia_inc',
+ },
+ alternates: {
+ canonical: 'https://errors.deessejs.com',
+ },
+};
+
// Floating squares data for blueprint aesthetic
const floatingSquares = [
{ x: 300, y: 120, opacity: 1.0, delay: 0.7 },
diff --git a/apps/web/src/app/docs/[[...slug]]/page.tsx b/apps/web/src/app/docs/[[...slug]]/page.tsx
index 53ce219..32d40ab 100644
--- a/apps/web/src/app/docs/[[...slug]]/page.tsx
+++ b/apps/web/src/app/docs/[[...slug]]/page.tsx
@@ -11,7 +11,7 @@ import { notFound } from 'next/navigation';
import { getMDXComponents } from '@/components/mdx';
import type { Metadata } from 'next';
import { createRelativeLink } from 'fumadocs-ui/mdx';
-import { gitConfig } from '@/lib/shared';
+import { gitConfig, siteUrl } from '@/lib/shared';
export default async function Page(props: PageProps<'/docs/[[...slug]]'>) {
const params = await props.params;
@@ -56,6 +56,9 @@ export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): P
return {
title: page.data.title,
description: page.data.description,
+ alternates: {
+ canonical: `${siteUrl}${page.url}`,
+ },
openGraph: {
images: getPageImage(page).url,
},
diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx
index 42a0b4f..3330cd2 100644
--- a/apps/web/src/app/layout.tsx
+++ b/apps/web/src/app/layout.tsx
@@ -11,6 +11,9 @@ const inter = Inter({
export default function Layout({ children }: LayoutProps<'/'>) {
return (
+
+
+
{children}
diff --git a/apps/web/src/app/og/docs/[...slug]/route.tsx b/apps/web/src/app/og/docs/[...slug]/route.tsx
index 877166d..518a98c 100644
--- a/apps/web/src/app/og/docs/[...slug]/route.tsx
+++ b/apps/web/src/app/og/docs/[...slug]/route.tsx
@@ -8,7 +8,16 @@ export const revalidate = false;
export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...slug]'>) {
const { slug } = await params;
- const page = source.getPage(slug.slice(0, -1));
+
+ // getPageImage() appends 'image.png' to the slug array.
+ // Strip it to get back the real page slugs.
+ // Defensive: only strip if the last segment is exactly 'image.png'.
+ const cleanSlug =
+ slug.length > 1 && slug[slug.length - 1] === 'image.png'
+ ? slug.slice(0, -1)
+ : slug;
+
+ const page = source.getPage(cleanSlug);
if (!page) notFound();
return new ImageResponse(
@@ -22,7 +31,6 @@ export async function GET(_req: Request, { params }: RouteContext<'/og/docs/[...
export function generateStaticParams() {
return source.getPages().map((page) => ({
- lang: page.locale,
slug: getPageImage(page).segments,
}));
}
diff --git a/apps/web/src/app/og/home/route.tsx b/apps/web/src/app/og/home/route.tsx
new file mode 100644
index 0000000..ff870cd
--- /dev/null
+++ b/apps/web/src/app/og/home/route.tsx
@@ -0,0 +1,19 @@
+import { ImageResponse } from 'next/og';
+import { generate as DefaultImage } from 'fumadocs-ui/og';
+import { appName } from '@/lib/shared';
+
+export const revalidate = false;
+
+export async function GET() {
+ return new ImageResponse(
+ ,
+ {
+ width: 1200,
+ height: 630,
+ },
+ );
+}
diff --git a/apps/web/src/app/robots.ts b/apps/web/src/app/robots.ts
new file mode 100644
index 0000000..ca31f53
--- /dev/null
+++ b/apps/web/src/app/robots.ts
@@ -0,0 +1,14 @@
+import type { MetadataRoute } from 'next';
+
+export default function robots(): MetadataRoute.Robots {
+ return {
+ rules: [
+ {
+ userAgent: '*',
+ allow: '/',
+ disallow: ['/api/search', '/llms.mdx'],
+ },
+ ],
+ sitemap: 'https://errors.deessejs.com/sitemap.xml',
+ };
+}
diff --git a/apps/web/src/app/sitemap.ts b/apps/web/src/app/sitemap.ts
new file mode 100644
index 0000000..f0ea468
--- /dev/null
+++ b/apps/web/src/app/sitemap.ts
@@ -0,0 +1,27 @@
+import type { MetadataRoute } from 'next';
+import { source } from '@/lib/source';
+import { siteUrl } from '@/lib/shared';
+import { getPageImage } from '@/lib/source';
+
+export default function sitemap(): MetadataRoute.Sitemap {
+ const pages = source.getPages();
+
+ const docPages = pages.map((page) => ({
+ url: `${siteUrl}${page.url}`,
+ lastModified: new Date(),
+ changeFrequency: 'weekly' as const,
+ priority: page.url === '/docs' ? 1.0 : 0.8,
+ images: [`${siteUrl}${getPageImage(page).url}`],
+ }));
+
+ const staticPages: MetadataRoute.Sitemap = [
+ {
+ url: siteUrl,
+ lastModified: new Date(),
+ changeFrequency: 'monthly',
+ priority: 0.9,
+ },
+ ];
+
+ return [...staticPages, ...docPages];
+}
diff --git a/apps/web/src/lib/shared.ts b/apps/web/src/lib/shared.ts
index 077db91..c562b06 100644
--- a/apps/web/src/lib/shared.ts
+++ b/apps/web/src/lib/shared.ts
@@ -2,6 +2,7 @@ export const appName = 'DeesseJS Errors';
export const docsRoute = '/docs';
export const docsImageRoute = '/og/docs';
export const docsContentRoute = '/llms.mdx/docs';
+export const siteUrl = 'https://errors.deessejs.com';
export const gitConfig = {
user: 'nesalia-inc',