SDK

Metadata

Define site-wide SEO defaults and generate Next.js-compatible Metadata objects for every page.

defineSEO(config)

Define global SEO defaults for your site. Returns a frozen config object used by createMetadata() and other SDK functions.

seo.config.tstypescript
import { defineSEO } from 'indxel'

export default defineSEO({
  siteName: 'My SaaS',
  siteUrl: 'https://mysaas.com',
  titleTemplate: '%s | My SaaS',
  defaultDescription: 'Build faster with My SaaS.',
  defaultOGImage: '/og-default.png',
  locale: 'en_US',
  twitter: {
    handle: '@mysaas',
    cardType: 'summary_large_image',
  },
  organization: {
    name: 'My SaaS Inc.',
    logo: '/logo.png',
    url: 'https://mysaas.com',
  },
})
ParameterTypeDescription
siteName*stringYour site or brand name
siteUrl*stringFull base URL (https://...)
titleTemplatestringTitle pattern. %s is replaced by the page title.
defaultDescriptionstringFallback meta description when page has none
defaultOGImagestringFallback OpenGraph image path
localestringDefault locale (e.g. 'en_US')
twitter.handlestringTwitter/X handle (e.g. '@mysaas')
twitter.cardType'summary' | 'summary_large_image'Twitter card type
organizationobjectOrganization info for structured data: name, logo, url

Single source of truth

Define your config once in seo.config.ts at the root of your project. Import it everywhere.

createMetadata(page, config?)

Generate a Next.js-compatible Metadata object. Use directly in your page's generateMetadata() function.

Basic page

app/pricing/page.tsxtypescript
import { createMetadata } from 'indxel'
import seoConfig from '@/seo.config'

export function generateMetadata() {
  return createMetadata({
    title: 'Pricing',
    description: 'Simple pricing. Start free.',
    path: '/pricing',
    ogImage: '/og-pricing.png',  // optional, falls back to defaultOGImage
  }, seoConfig)
}

Article page

app/blog/[slug]/page.tsxtypescript
import { createMetadata } from 'indxel'
import seoConfig from '@/seo.config'

export function generateMetadata({ params }) {
  const post = getPost(params.slug)

  return createMetadata({
    title: post.title,
    description: post.excerpt,
    path: `/blog/${post.slug}`,
    article: {
      publishedTime: post.publishedAt,
      modifiedTime: post.updatedAt,
      author: post.author,
      tags: post.tags,
    },
  }, seoConfig)
}

Page parameters

ParameterTypeDescription
title*stringPage title (inserted into titleTemplate)
description*stringMeta description (120-160 chars recommended)
pathstringURL path (e.g. '/pricing'). Combined with siteUrl for canonical.
ogImagestringOpenGraph image path. Falls back to defaultOGImage.
noIndexbooleanSet robots to noindex, nofollow
articleobjectArticle metadata: publishedTime, modifiedTime, author, tags

What it generates

createMetadata() produces:

  • Title with template applied
  • Canonical URL (absolute)
  • OpenGraph tags (title, description, image, type, locale)
  • Twitter card (summary_large_image by default)
  • Hreflang alternates
  • Robots directives

Info

The output is a standard Next.js Metadata object. It works directly with the App Router's generateMetadata() pattern.