{"_id":"@alloylab/seo","name":"@alloylab/seo","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.1":{"name":"@alloylab/seo","version":"1.0.1","description":"SEO utilities and components for modern web applications","main":"dist/index.js","type":"module","bin":{"seo-cli":"dist/cli/index.js"},"keywords":["seo","meta-tags","structured-data","sitemap","react","typescript","json-ld","open-graph","twitter-cards"],"author":{"name":"Stephen Way","email":"stephen@stephenway.net"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alloy-lab/overland.git","directory":"packages/seo"},"bugs":{"url":"https://github.com/alloy-lab/overland/issues"},"homepage":"https://github.com/alloy-lab/overland/tree/main/packages/seo#readme","engines":{"node":">=18.0.0"},"peerDependencies":{"react":">=18.0.0","payload":">=3.0.0"},"dependencies":{"commander":"^12.1.0"},"devDependencies":{"@commitlint/cli":"^19.8.1","@commitlint/config-conventional":"^19.8.1","@eslint/js":"^9.16.0","@testing-library/jest-dom":"^6.4.2","@testing-library/react":"^15.0.0","@types/node":"^24.5.2","@types/react":"^18.3.12","@vitest/coverage-v8":"^3.2.4","eslint":"^9.16.0","jsdom":"^25.0.1","lefthook":"^1.13.2","prettier":"^3.6.2","react":"^18.3.1","react-dom":"^18.3.1","typescript":"^5.9.2","typescript-eslint":"^8.16.0","vitest":"^3.2.4"},"scripts":{"build":"tsc","dev":"tsc --watch","test":"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","docs:serve":"node scripts/serve-docs.js 8080","docs:serve:python":"cd docs && python3 -m http.server 8080","docs:build":"npm run build && mkdir -p docs/assets && cp -r dist docs/assets/ && cp package.json docs/assets/","test:watch":"vitest --watch","lint":"eslint src --ext .js,.ts,.tsx","lint:fix":"eslint src --ext .js,.ts,.tsx --fix","commitlint":"commitlint","format":"prettier --write .","format:check":"prettier --check .","typecheck":"tsc --noEmit","typecheck:test":"tsc --noEmit --project tsconfig.test.json","clean":"rm -rf dist","prebuild":"npm run clean","hooks:install":"lefthook install","hooks:uninstall":"lefthook uninstall","version":"npm run format && git add -A","postversion":"git push && git push --tags"},"_id":"@alloylab/seo@1.0.1","types":"./dist/index.d.ts","_integrity":"sha512-sZyQI46Ejk0DRIKQAnS56V5N629GWBzRU0yQ8XEUvDgJHFdV32AdITT8nCgBDFNOseMwbMPimNLOTubDfds5DA==","_resolved":"/tmp/6ae6da1feed400537831097b923f35e6/alloylab-seo-1.0.1.tgz","_from":"file:alloylab-seo-1.0.1.tgz","_nodeVersion":"22.19.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-sZyQI46Ejk0DRIKQAnS56V5N629GWBzRU0yQ8XEUvDgJHFdV32AdITT8nCgBDFNOseMwbMPimNLOTubDfds5DA==","shasum":"743fd89e2965165fc55735b2d0774254013740be","tarball":"https://registry.npmjs.org/@alloylab/seo/-/seo-1.0.1.tgz","fileCount":66,"unpackedSize":126887,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCfVN3UnUFMKGgkNz2dZ8YYYXY9pLmnQVDlSifNYK499QIgVRThRJOW8GCq/zpiB6kFqZw+7hQgbHAh0c1WpZX51Vo="}]},"_npmUser":{"name":"stephenway","email":"stephen@stephenway.net"},"directories":{},"maintainers":[{"name":"stephenway","email":"stephen@stephenway.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/seo_1.0.1_1759007233500_0.8492224688476979"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-27T21:07:13.415Z","1.0.1":"2025-09-27T21:07:13.692Z","modified":"2025-09-27T21:07:13.961Z"},"maintainers":[{"name":"stephenway","email":"stephen@stephenway.net"}],"description":"SEO utilities and components for modern web applications","homepage":"https://github.com/alloy-lab/overland/tree/main/packages/seo#readme","keywords":["seo","meta-tags","structured-data","sitemap","react","typescript","json-ld","open-graph","twitter-cards"],"repository":{"type":"git","url":"git+https://github.com/alloy-lab/overland.git","directory":"packages/seo"},"author":{"name":"Stephen Way","email":"stephen@stephenway.net"},"bugs":{"url":"https://github.com/alloy-lab/overland/issues"},"license":"MIT","readme":"# @alloylab/seo\n\n[![npm version](https://badge.fury.io/js/%40alloylab%2Fseo.svg)](https://badge.fury.io/js/%40alloy-lab%2Fseo)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nSEO utilities and components for modern web applications. This package provides comprehensive SEO tools including meta tag generation, structured data (JSON-LD), sitemap generation, and React components.\n\n## Features\n\n- 🏷️ **Meta Tag Generation**: Automatic Open Graph, Twitter Cards, and standard meta tags\n- 📊 **Structured Data**: JSON-LD schema generation for Schema.org\n- 🗺️ **Sitemap Generation**: XML sitemap and robots.txt utilities\n- ⚛️ **React Hooks**: `useSEO()` hook for React applications\n- 🔥 **Next.js App Router**: `generateMetadata()` helper for App Router\n- 🎯 **SvelteKit Support**: Native SvelteKit integration\n- 📱 **React Components**: Ready-to-use SEO components for React applications\n- 🔧 **TypeScript Support**: Full TypeScript definitions and type safety\n- 📦 **Framework Agnostic**: Works with any frontend framework\n- ⚡ **Performance**: Optimized for speed and bundle size (< 1KB core)\n- 🎯 **SEO Optimized**: Follows best practices for search engine optimization\n\n## Installation\n\n```bash\nnpm install @alloylab/seo\n# or\nyarn add @alloylab/seo\n# or\npnpm add @alloylab/seo\n```\n\n## Quick Start\n\n### Framework-Specific Usage\n\n#### React with Hooks\n\n```typescript\nimport { useSEO } from '@alloylab/seo';\n\nfunction MyPage({ page }) {\n  const { title, description, metaTags } = useSEO({\n    siteSettings: { siteName: 'My Site' },\n    page,\n    baseUrl: 'https://mysite.com',\n    type: 'page'\n  });\n\n  return (\n    <div>\n      <head>{metaTags}</head>\n      <h1>{title}</h1>\n    </div>\n  );\n}\n```\n\n#### Next.js App Router\n\n```typescript\nimport { generateMetadata } from '@alloylab/seo/nextjs';\n\nexport async function generateMetadata({ params }) {\n  const page = await getPage(params.slug);\n\n  return generateMetadata({\n    siteSettings: { siteName: 'My Site' },\n    page,\n    baseUrl: 'https://mysite.com',\n    type: 'page',\n  });\n}\n```\n\n#### SvelteKit\n\n```typescript\n// +page.ts\nimport { generateSEOData } from '@alloylab/seo/sveltekit';\n\nexport const load = async () => {\n  const seo = generateSEOData({\n    siteSettings: { siteName: 'My Site' },\n    baseUrl: 'https://mysite.com',\n    type: 'home',\n  });\n\n  return { seo };\n};\n```\n\n### 1. Basic SEO Generation\n\n```typescript\nimport { generateSEO, generateMetaTags } from '@alloylab/seo';\n\nconst siteSettings = {\n  siteName: 'My Website',\n  siteDescription: 'A modern website',\n};\n\nconst page = {\n  id: '1',\n  title: 'About Us',\n  slug: 'about',\n  status: 'published',\n  seo: {\n    title: 'About Our Company',\n    description: 'Learn more about our company and mission',\n    keywords: 'about, company, mission',\n  },\n  createdAt: '2024-01-01T00:00:00.000Z',\n  updatedAt: '2024-01-01T00:00:00.000Z',\n};\n\n// Generate SEO data\nconst seo = generateSEO(page, siteSettings, 'page', 'https://example.com');\n\n// Generate HTML meta tags\nconst metaTags = generateMetaTags(seo);\nconsole.log(metaTags);\n```\n\n### 2. React Components\n\n```tsx\nimport { SEOHead, StructuredData } from '@alloylab/seo';\n\nfunction MyPage() {\n  const seo = generateSEO(page, siteSettings, 'page', 'https://example.com');\n\n  return (\n    <html>\n      <head>\n        <SEOHead seo={seo} />\n        <StructuredData\n          baseUrl=\"https://example.com\"\n          siteSettings={siteSettings}\n          page={page}\n        />\n      </head>\n      <body>\n        <h1>{page.title}</h1>\n      </body>\n    </html>\n  );\n}\n```\n\n### 3. Sitemap Generation\n\n```typescript\nimport {\n  generateSitemapUrls,\n  generateSitemapXML,\n  generateRobotsTxt,\n} from '@alloylab/seo';\n\nconst pages = [\n  /* your pages array */\n];\nconst siteSettings = {\n  /* your site settings */\n};\n\n// Generate sitemap URLs\nconst urls = generateSitemapUrls(pages, siteSettings, {\n  baseUrl: 'https://example.com',\n  includeHomepage: true,\n  homepagePriority: 1.0,\n  pagePriority: 0.8,\n});\n\n// Generate XML sitemap\nconst sitemapXML = generateSitemapXML(urls);\n\n// Generate robots.txt\nconst robotsTxt = generateRobotsTxt('https://example.com');\n```\n\n## API Reference\n\n### Components\n\n#### `SEOHead`\n\nReact component for rendering SEO meta tags.\n\n```tsx\ninterface SEOHeadProps {\n  seo: SEOData;\n}\n\n<SEOHead seo={seoData} />;\n```\n\n#### `StructuredData`\n\nReact component for injecting JSON-LD structured data.\n\n```tsx\ninterface StructuredDataProps {\n  baseUrl: string;\n  siteSettings: SiteSettings;\n  page?: Page;\n  breadcrumbs?: Array<{ name: string; url: string }>;\n}\n\n<StructuredData\n  baseUrl=\"https://example.com\"\n  siteSettings={siteSettings}\n  page={page}\n  breadcrumbs={breadcrumbs}\n/>;\n```\n\n### Utilities\n\n#### `generateSEO`\n\nGenerates comprehensive SEO data for pages or site settings.\n\n```typescript\nfunction generateSEO(\n  data: Page | SiteSettings,\n  siteSettings: SiteSettings,\n  type: 'page' | 'home' = 'home',\n  baseUrl?: string,\n  breadcrumbs?: Array<{ name: string; url: string }>\n): SEOData;\n```\n\n#### `generateMetaTags`\n\nGenerates HTML meta tags from SEO data.\n\n```typescript\nfunction generateMetaTags(seo: SEOData): string;\n```\n\n#### `generateStructuredData`\n\nGenerates JSON-LD structured data for Schema.org.\n\n```typescript\nfunction generateStructuredData(config: StructuredDataConfig): string;\n```\n\n#### `generateSitemapUrls`\n\nGenerates sitemap URLs from pages collection.\n\n```typescript\nfunction generateSitemapUrls(\n  pages: Page[],\n  siteSettings: SiteSettings,\n  config?: Partial<SitemapConfig>\n): SitemapUrl[];\n```\n\n#### `generateSitemapXML`\n\nGenerates XML sitemap from URLs.\n\n```typescript\nfunction generateSitemapXML(urls: SitemapUrl[]): string;\n```\n\n#### `generateRobotsTxt`\n\nGenerates robots.txt content.\n\n```typescript\nfunction generateRobotsTxt(baseUrl: string): string;\n```\n\n## Schema.org Support\n\nThe package includes utilities for generating various Schema.org structured data types:\n\n- **WebSite**: Basic website information\n- **Article**: Blog posts and articles\n- **BreadcrumbList**: Navigation breadcrumbs\n- **FAQPage**: Frequently asked questions\n- **LocalBusiness**: Local business information\n- **Product**: E-commerce products\n\n### Example: FAQ Schema\n\n```typescript\nimport { generateFAQSchema } from '@alloylab/seo';\n\nconst faqs = [\n  {\n    question: 'What is your return policy?',\n    answer: 'We offer a 30-day return policy for all products.',\n  },\n  {\n    question: 'How long does shipping take?',\n    answer: 'Standard shipping takes 3-5 business days.',\n  },\n];\n\nconst faqSchema = generateFAQSchema(faqs);\n```\n\n## Type Definitions\n\nThe package provides comprehensive TypeScript definitions:\n\n```typescript\ninterface SEOData {\n  title: string;\n  description: string;\n  keywords?: string;\n  image?: string;\n  url?: string;\n  type?: string;\n  structuredData?: string;\n}\n\ninterface Page {\n  id: string;\n  title: string;\n  slug: string;\n  status: 'draft' | 'published';\n  excerpt?: string;\n  featuredImage?: Media;\n  seo?: SEOFields;\n  publishedDate?: string;\n  createdAt: string;\n  updatedAt: string;\n}\n\ninterface SiteSettings {\n  siteName?: string;\n  siteDescription?: string;\n  logo?: Media;\n  socialMedia?: {\n    twitter?: string;\n    facebook?: string;\n    instagram?: string;\n    linkedin?: string;\n    youtube?: string;\n  };\n  contactInfo?: {\n    email?: string;\n    phone?: string;\n    address?: string;\n  };\n}\n```\n\n## Integration Examples\n\n### Next.js\n\n```tsx\n// pages/_document.tsx\nimport { SEOHead } from '@alloylab/seo';\n\nexport default function Document() {\n  return (\n    <Html>\n      <Head>\n        <SEOHead seo={seoData} />\n      </Head>\n      <body>\n        <Main />\n        <NextScript />\n      </body>\n    </Html>\n  );\n}\n```\n\n### React Router\n\n```tsx\n// app/root.tsx\nimport { SEOHead } from '@alloylab/seo';\n\nexport default function Root() {\n  return (\n    <html>\n      <head>\n        <SEOHead seo={seoData} />\n      </head>\n      <body>\n        <Outlet />\n      </body>\n    </html>\n  );\n}\n```\n\n### SvelteKit\n\n```svelte\n<!-- app.html -->\n<script>\n  import { generateSEO, generateMetaTags } from '@alloylab/seo';\n\n  export let seoData;\n  const metaTags = generateMetaTags(seoData);\n</script>\n\n<head>\n  {@html metaTags}\n</head>\n```\n\n## Best Practices\n\n1. **Always provide fallbacks**: Use site settings as fallbacks for missing page SEO data\n2. **Include structured data**: Add JSON-LD structured data for better search engine understanding\n3. **Generate sitemaps**: Automatically generate and update sitemaps for better crawling\n4. **Use proper meta tags**: Include Open Graph and Twitter Card meta tags for social sharing\n5. **Validate your data**: Use TypeScript types to ensure data integrity\n\n## Contributing\n\nContributions are welcome! Please read our [Contributing Guide](../../CONTRIBUTING.md) for details.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details.\n\n## Support\n\n- 📖 [Documentation](https://github.com/alloy-lab/overland/tree/main/packages/seo#readme)\n- 🐛 [Issue Tracker](https://github.com/alloy-lab/overland/issues)\n- 💬 [Discussions](https://github.com/alloy-lab/overland/discussions)\n","readmeFilename":"README.md","_rev":"1-4177a03d1cbce24a631ef15c67d061eb"}