{"_id":"@avenra/metadatax","name":"@avenra/metadatax","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@avenra/metadatax","version":"0.2.0","description":"Lightweight metadata and SEO manager for React and Next.js","keywords":["seo","metadata","nextjs","react","json-ld","open-graph"],"homepage":"https://github.com/DevSam7t3/metadatax","bugs":{"url":"https://github.com/DevSam7t3/metadatax/issues"},"repository":{"type":"git","url":"git+https://github.com/DevSam7t3/metadatax.git"},"license":"MIT","type":"module","sideEffects":false,"engines":{"node":">=20"},"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./pages":{"types":"./dist/pages.d.ts","import":"./dist/pages.js"},"./next-plugin":{"types":"./dist/next-plugin.d.ts","import":"./dist/next-plugin.js"},"./package.json":{"default":"./package.json"}},"scripts":{"build":"tsc -p tsconfig.json","test":"vitest run","test:watch":"vitest","release:check":"npm test && npm run build && npm pack --dry-run","prepublishOnly":"npm test && npm run build"},"publishConfig":{"access":"public"},"peerDependencies":{"react":">=18"},"devDependencies":{"@types/react":"^18.3.12","typescript":"^5.7.2","vitest":"^2.1.9"},"_id":"@avenra/metadatax@0.2.0","gitHead":"db5d430900eae5e0b70e461424c6b437964db6a4","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-CIeTNo71jvIT/ZdhajB9skJ3uk7ud9XUpSb61QU4K/K1BcBR2/si9LaAgC2Ry1iJosDwpNqiypqri7jGPn/NRg==","shasum":"ced9b28184becc5ca6ed9b404bc28f753ef1bdb0","tarball":"https://registry.npmjs.org/@avenra/metadatax/-/metadatax-0.2.0.tgz","fileCount":42,"unpackedSize":56142,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEP7L+hD250K8tyFq0qfagh7TJhDlQRjV00ut6RGXm1RAiBhzTDvG2ekhS0OLAokLIecI64LoKA8FIKOr8u9xW4j/Q=="}]},"_npmUser":{"name":"devsam7t3","email":"samirashid54222@gmail.com"},"directories":{},"maintainers":[{"name":"devsam7t3","email":"samirashid54222@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/metadatax_0.2.0_1776239621397_0.9923707374078683"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-15T07:53:41.301Z","0.2.0":"2026-04-15T07:53:41.577Z","modified":"2026-04-15T07:53:41.885Z"},"maintainers":[{"name":"devsam7t3","email":"samirashid54222@gmail.com"}],"description":"Lightweight metadata and SEO manager for React and Next.js","homepage":"https://github.com/DevSam7t3/metadatax","keywords":["seo","metadata","nextjs","react","json-ld","open-graph"],"repository":{"type":"git","url":"git+https://github.com/DevSam7t3/metadatax.git"},"bugs":{"url":"https://github.com/DevSam7t3/metadatax/issues"},"license":"MIT","readme":"# @avenra/metadatax\r\n\r\n[![npm version](https://img.shields.io/npm/v/@avenra/metadatax)](https://www.npmjs.com/package/@avenra/metadatax)\r\n[![license](https://img.shields.io/npm/l/@avenra/metadatax)](./LICENSE)\r\n[![CI](https://img.shields.io/github/actions/workflow/status/avenra/metadatax/ci.yml?branch=main)](https://github.com/avenra/metadatax/actions/workflows/ci.yml)\r\n\r\nProduction-ready SEO and metadata utilities for Next.js and React with a single API surface.\r\n\r\n## Table of Contents\r\n\r\n- [Why MetadataX](#why-metadatax)\r\n- [Package Entry Points](#package-entry-points)\r\n- [Installation](#installation)\r\n- [Quick Start](#quick-start)\r\n- [API Reference](#api-reference)\r\n- [Smart Defaults Behavior](#smart-defaults-behavior)\r\n- [SEO Linting Rules](#seo-linting-rules)\r\n- [Example App](#example-app)\r\n- [Migration Guide](#migration-guide)\r\n- [Contributing](#contributing)\r\n- [Security](#security)\r\n- [License](#license)\r\n\r\n## Why MetadataX\r\n\r\n- Works with Next.js App Router and Pages Router.\r\n- Supports React component usage for head tag rendering.\r\n- Provides smart default generation for missing metadata.\r\n- Includes development linting for common SEO problems.\r\n- Ships tree-shakable exports.\r\n\r\n## Package Entry Points\r\n\r\n- App Router and default exports: `@avenra/metadatax`\r\n- Pages Router exports: `@avenra/metadatax/pages`\r\n- Next.js build plugin: `@avenra/metadatax/next-plugin`\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @avenra/metadatax\r\n```\r\n\r\n## Quick Start\r\n\r\n### App Router\r\n\r\n```ts\r\n// seo.config.ts\r\nimport { defineSeoConfig } from \"@avenra/metadatax\";\r\n\r\nexport const seo = defineSeoConfig({\r\n    baseUrl: \"https://example.com\",\r\n    title: \"Example Site\",\r\n    description: \"Production-ready metadata defaults.\",\r\n    canonical: \"/\",\r\n    titleTemplate: \"%s | Example\",\r\n    openGraph: {\r\n        type: \"website\",\r\n        images: [{ url: \"/og/default.png\" }],\r\n    },\r\n    auto: {\r\n        titleFromPath: true,\r\n        descriptionFromContent: true,\r\n    },\r\n    lint: {\r\n        strict: true,\r\n        rules: {\r\n            titleLength: 100,\r\n            duplicate_title: \"warn\",\r\n        },\r\n    },\r\n});\r\n```\r\n\r\n```mjs\r\n// next.config.mjs\r\nimport { withMetadataX } from \"@avenra/metadatax/next-plugin\";\r\n\r\n/** @type {import('next').NextConfig} */\r\nconst nextConfig = {\r\n    reactStrictMode: true,\r\n};\r\n\r\nexport default withMetadataX(nextConfig, {\r\n    failOn: \"error\",\r\n});\r\n```\r\n\r\n```ts\r\n// app/layout.tsx\r\nimport type { Metadata } from \"next\";\r\nimport { createMetadata } from \"@avenra/metadatax\";\r\nimport { seo } from \"../seo.config\";\r\n\r\nexport const metadata: Metadata = createMetadata(seo, {});\r\n```\r\n\r\n```tsx\r\n// app/blog/[slug]/page.tsx\r\nimport { JsonLd, articleJsonLd } from \"@avenra/metadatax\";\r\n\r\nexport default function BlogPage() {\r\n    return (\r\n        <JsonLd\r\n            data={articleJsonLd({\r\n                headline: \"My First Post\",\r\n                author: \"Avenra Team\",\r\n                datePublished: \"2026-04-14\",\r\n            })}\r\n        />\r\n    );\r\n}\r\n```\r\n\r\n### Pages Router\r\n\r\n```tsx\r\nimport { Meta, defineSeoConfig } from \"@avenra/metadatax/pages\";\r\n\r\ndefineSeoConfig({\r\n    baseUrl: \"https://example.com\",\r\n    auto: { titleFromPath: true },\r\n});\r\n\r\nexport default function AboutPage() {\r\n    return <Meta canonical=\"/about\" />;\r\n}\r\n```\r\n\r\n## API Reference\r\n\r\n### Root Exports (`@avenra/metadatax`)\r\n\r\n- `defineSeoConfig`\r\n- `defineSeoDefaults`\r\n- `createMetadata`\r\n- `createHeadEntries`\r\n- `createResolvedMeta`\r\n- `Meta`\r\n- `JsonLd`\r\n- `articleJsonLd`\r\n- `breadcrumbJsonLd`\r\n- `organizationJsonLd`\r\n- `productJsonLd`\r\n\r\n### Plugin Exports (`@avenra/metadatax/next-plugin`)\r\n\r\n- `withMetadataX`\r\n\r\n### Pages Exports (`@avenra/metadatax/pages`)\r\n\r\n- `defineSeoConfig`\r\n- `createHeadEntries`\r\n- `Meta`\r\n- `JsonLd`\r\n\r\n### `defineSeoConfig(config)`\r\n\r\nStores and returns global runtime config.\r\n\r\n| Prop            | Type                                 | Required | Notes                                         |\r\n| --------------- | ------------------------------------ | -------- | --------------------------------------------- |\r\n| `baseUrl`       | `string`                             | No       | Used to absolutize canonical and OG URLs.     |\r\n| `titleTemplate` | `string`                             | No       | Supports `%s` placeholder.                    |\r\n| `defaultTitle`  | `string`                             | No       | Fallback title when none is provided/derived. |\r\n| `title`         | `string \\| null`                     | No       | Global default title.                         |\r\n| `description`   | `string \\| null`                     | No       | Global default description.                   |\r\n| `canonical`     | `string \\| null`                     | No       | Global canonical URL/path.                    |\r\n| `robots`        | `SeoRobots \\| null`                  | No       | Robots defaults.                              |\r\n| `openGraph`     | `OpenGraphInput \\| null`             | No       | Open Graph defaults.                          |\r\n| `twitter`       | `TwitterInput \\| null`               | No       | Twitter defaults.                             |\r\n| `jsonLd`        | `JsonLdNode \\| JsonLdNode[] \\| null` | No       | Global JSON-LD nodes.                         |\r\n| `auto`          | `AutoConfig`                         | No       | Smart defaults controls.                      |\r\n| `lint`          | `LintConfig`                         | No       | Dev lint behavior controls.                   |\r\n\r\nWhen `lint.strict` is set to `true`, `title`, `description`, `canonical`, and `openGraph` become required in config typing.\r\n\r\n#### `AutoConfig`\r\n\r\n| Prop                     | Type                           | Required | Notes                                               |\r\n| ------------------------ | ------------------------------ | -------- | --------------------------------------------------- |\r\n| `titleFromPath`          | `boolean`                      | No       | Derives title from route segment.                   |\r\n| `titleFromH1`            | `boolean`                      | No       | Uses `ResolveContext.h1` when available.            |\r\n| `descriptionFromContent` | `boolean`                      | No       | Uses extractor/content text with fallback behavior. |\r\n| `contentExtractor`       | `(ctx) => string \\| undefined` | No       | Custom extraction logic.                            |\r\n\r\n#### `LintConfig`\r\n\r\n| Prop     | Type        | Required | Notes                                                       |\r\n| -------- | ----------- | -------- | ----------------------------------------------------------- |\r\n| `strict` | `boolean`   | No       | Default level fallback. `true` elevates unconfigured rules. |\r\n| `rules`  | `LintRules` | No       | Per-rule override map and threshold controls.               |\r\n\r\n`LintRules` supports issue-level overrides: `missing_title`, `missing_description`, `missing_opengraph`, `missing_canonical`, `missing_og_image`, `title_too_long`, and `duplicate_title`.\r\n\r\nRule values:\r\n\r\n- `\"warn\"` to force warning level\r\n- `\"error\"` to force error level\r\n- `false` to disable a rule\r\n\r\nSpecial threshold rule:\r\n\r\n- `titleLength: number | false` (`60` by default)\r\n\r\n### `withMetadataX(nextConfig, options?)`\r\n\r\nWraps Next.js config and injects build-time lint fail mode.\r\n\r\n| Prop      | Type                                     | Required | Notes                                           |\r\n| --------- | ---------------------------------------- | -------- | ----------------------------------------------- |\r\n| `options` | `{ failOn?: \"error\"\\|\"warning\"\\|\"all\" }` | No       | Build failure threshold. Defaults to `\"error\"`. |\r\n\r\nFail mode behavior:\r\n\r\n- `error`: fail build on lint issues with `level === \"error\"`\r\n- `warning`: fail build on warnings and errors\r\n- `all`: fail build on any lint issue\r\n\r\n### `defineSeoDefaults(config)`\r\n\r\nReturns config for server-focused usage patterns (for example factory-based metadata composition).\r\n\r\n| Prop     | Type        | Required | Notes                            |\r\n| -------- | ----------- | -------- | -------------------------------- |\r\n| `config` | `SeoConfig` | Yes      | Same shape as `defineSeoConfig`. |\r\n\r\n### `createMetadata(defaults, input?, context?)`\r\n\r\nReturns a Next.js-compatible metadata object.\r\n\r\n| Prop       | Type             | Required | Notes                                      |\r\n| ---------- | ---------------- | -------- | ------------------------------------------ |\r\n| `defaults` | `SeoConfig`      | Yes      | Base config source.                        |\r\n| `input`    | `MetaInput`      | No       | Route/page overrides.                      |\r\n| `context`  | `ResolveContext` | No       | Route/runtime context for derivation/lint. |\r\n\r\n### `createResolvedMeta(input, context?, defaults?)`\r\n\r\nResolves metadata and returns lint results.\r\n\r\n| Prop       | Type             | Required | Notes                                                        |\r\n| ---------- | ---------------- | -------- | ------------------------------------------------------------ |\r\n| `input`    | `MetaInput`      | Yes      | Route/page metadata input.                                   |\r\n| `context`  | `ResolveContext` | No       | Includes `pathname`, `routeKey`, `h1`, `contentText`, `env`. |\r\n| `defaults` | `SeoConfig`      | No       | Falls back to global config when omitted.                    |\r\n\r\nReturn shape:\r\n\r\n| Field        | Type           | Notes                  |\r\n| ------------ | -------------- | ---------------------- |\r\n| `resolved`   | `ResolvedMeta` | Final merged metadata. |\r\n| `lintIssues` | `LintIssue[]`  | Dev lint findings.     |\r\n\r\n### `createHeadEntries(input, context?, defaults?)`\r\n\r\nSerializes resolved metadata into renderable head entries.\r\n\r\n| Prop       | Type             | Required | Notes                             |\r\n| ---------- | ---------------- | -------- | --------------------------------- |\r\n| `input`    | `MetaInput`      | Yes      | Route/page metadata input.        |\r\n| `context`  | `ResolveContext` | No       | Context for derive/lint behavior. |\r\n| `defaults` | `SeoConfig`      | No       | Optional config override.         |\r\n\r\nReturn shape:\r\n\r\n| Field        | Type          | Notes                         |\r\n| ------------ | ------------- | ----------------------------- |\r\n| `entries`    | `HeadEntry[]` | Title/meta/link/script nodes. |\r\n| `lintIssues` | `LintIssue[]` | Dev lint findings.            |\r\n\r\n### `<Meta />`\r\n\r\nReact component that renders computed head tags and emits dev lint logs.\r\n\r\n| Prop          | Type                                 | Required | Notes                         |\r\n| ------------- | ------------------------------------ | -------- | ----------------------------- |\r\n| `title`       | `string \\| null`                     | No       | Page title override.          |\r\n| `description` | `string \\| null`                     | No       | Page description override.    |\r\n| `canonical`   | `string \\| null`                     | No       | Canonical URL/path override.  |\r\n| `robots`      | `SeoRobots \\| null`                  | No       | Robots override.              |\r\n| `openGraph`   | `OpenGraphInput \\| null`             | No       | Open Graph override.          |\r\n| `twitter`     | `TwitterInput \\| null`               | No       | Twitter override.             |\r\n| `jsonLd`      | `JsonLdNode \\| JsonLdNode[] \\| null` | No       | JSON-LD override.             |\r\n| `context`     | `ResolveContext`                     | No       | Optional derive/lint context. |\r\n\r\n### `<JsonLd />`\r\n\r\nRenders one or multiple `application/ld+json` script tags.\r\n\r\n| Prop   | Type                                                   | Required | Notes                                      |\r\n| ------ | ------------------------------------------------------ | -------- | ------------------------------------------ |\r\n| `data` | `Record<string, unknown> \\| Record<string, unknown>[]` | Yes      | JSON-LD node(s). `@context` is auto-added. |\r\n\r\n### `articleJsonLd(input)`\r\n\r\nStructured helper for article schema data.\r\n\r\n| Prop            | Type     | Required | Notes                         |\r\n| --------------- | -------- | -------- | ----------------------------- |\r\n| `headline`      | `string` | Yes      | Article headline.             |\r\n| `description`   | `string` | No       | Article summary.              |\r\n| `datePublished` | `string` | No       | ISO timestamp/date.           |\r\n| `dateModified`  | `string` | No       | ISO timestamp/date.           |\r\n| `author`        | `string` | No       | Emits `Person` author object. |\r\n| `image`         | `string` | No       | Image URL.                    |\r\n| `url`           | `string` | No       | Canonical article URL.        |\r\n\r\n### `breadcrumbJsonLd(input)`\r\n\r\nStructured helper for breadcrumb schema data.\r\n\r\n| Prop             | Type                 | Required | Notes                                 |\r\n| ---------------- | -------------------- | -------- | ------------------------------------- |\r\n| `items`          | `BreadcrumbItem[]`   | No       | Single breadcrumb trail.              |\r\n| `multipleTrails` | `BreadcrumbItem[][]` | No       | Multiple trails, emitted as `@graph`. |\r\n\r\n`BreadcrumbItem`\r\n\r\n| Prop   | Type     | Required | Notes                    |\r\n| ------ | -------- | -------- | ------------------------ |\r\n| `name` | `string` | Yes      | Breadcrumb display name. |\r\n| `item` | `string` | No       | URL for breadcrumb item. |\r\n\r\n### `organizationJsonLd(input)`\r\n\r\nStructured helper for organization schema data.\r\n\r\n| Prop           | Type                                                           | Required | Notes                     |\r\n| -------------- | -------------------------------------------------------------- | -------- | ------------------------- |\r\n| `name`         | `string`                                                       | Yes      | Organization name.        |\r\n| `type`         | `\"Organization\" \\| \"OnlineStore\"`                              | No       | Schema type override.     |\r\n| `url`          | `string`                                                       | No       | Organization URL.         |\r\n| `logo`         | `string`                                                       | No       | Organization logo URL.    |\r\n| `description`  | `string`                                                       | No       | Organization description. |\r\n| `sameAs`       | `string[]`                                                     | No       | Social/profile URLs.      |\r\n| `contactPoint` | `{ contactType?: string; telephone?: string; email?: string }` | No       | Contact point details.    |\r\n\r\n### `productJsonLd(input)`\r\n\r\nStructured helper for product schema data.\r\n\r\n| Prop          | Type                                                                                      | Required | Notes                              |\r\n| ------------- | ----------------------------------------------------------------------------------------- | -------- | ---------------------------------- |\r\n| `name`        | `string`                                                                                  | Yes      | Product name.                      |\r\n| `description` | `string`                                                                                  | No       | Product description.               |\r\n| `image`       | `string \\| string[]`                                                                      | No       | Product image URL(s).              |\r\n| `sku`         | `string`                                                                                  | No       | Product SKU.                       |\r\n| `brand`       | `string`                                                                                  | No       | Brand name, emitted as `Brand`.    |\r\n| `offers`      | `{ price: number \\| string; priceCurrency: string; availability?: string; url?: string }` | No       | Offer details, emitted as `Offer`. |\r\n\r\n## Smart Defaults Behavior\r\n\r\n- `titleFromPath` derives from route/path segment:\r\n    - `/` -> `Home`\r\n    - `/posts/my-first-post` -> `My First Post`\r\n- `titleFromH1` has priority over path-derived title when `context.h1` is provided.\r\n- `descriptionFromContent` uses extractor/content text and truncates to 160 chars.\r\n- If description source is missing, it falls back to a derived label (`<Title> page`).\r\n\r\n## SEO Linting Rules\r\n\r\nCurrent dev lint checks:\r\n\r\n- `missing_canonical`\r\n- `missing_og_image`\r\n- `title_too_long` (over 60 chars)\r\n- `duplicate_title` (best-effort dev route registry)\r\n\r\nEach check can be overridden or disabled through `lint.rules`.\r\n\r\n## Example App\r\n\r\nReference app: `apps/nextjs-example`.\r\n\r\n```bash\r\ncd apps/nextjs-example\r\nnpm install\r\nnpm run dev\r\n```\r\n\r\n## Migration Guide\r\n\r\nIf you are moving from `next-seo`, use the migration document:\r\n\r\n- `docs/migrating-from-next-seo.md`\r\n\r\n## Contributing\r\n\r\nSee `CONTRIBUTING.md`.\r\n\r\n## Security\r\n\r\nSee `SECURITY.md`.\r\n\r\n## License\r\n\r\nMIT. See `LICENSE`.\r\n","readmeFilename":"README.md","_rev":"1-b988dd42bcef9d4ababbe76fd5ed391e"}