01 Software

Metadata

SEO metadata helper for Next.js

Metadata

A helper that converts the SEO meta field into a Next.js Metadata object.

Supported Collections

Products, Posts, Documents, Playlists, Galleries — any collection with the SEO plugin's meta field.

Installation

import { generateMetadata } from '@01.software/sdk/metadata'

Basic Usage

import type { Metadata } from 'next'
import { generateMetadata } from '@01.software/sdk/metadata'

export async function generateMetadata({ params }): Promise<Metadata> {
  const product = await client.from('products').findById(params.id, { depth: 1 })
  return generateMetadata(product)
}

With Fallback Options

return generateMetadata(product, {
  title: 'My Store',             // fallback when meta.title is empty
  description: 'Welcome',        // fallback when meta.description is empty
  siteName: 'My Store',          // og:site_name
})

Options

OptionTypeDescription
titlestringFallback title
descriptionstringFallback description
siteNamestringog:site_name value

Output

Returns a Next.js Metadata object with title, description, openGraph, and twitter fields.

When meta.image is a populated Media object (depth ≥ 1), it is included in openGraph.images and twitter.images. When the image is an unpopulated ID (depth 0), it is omitted.

QueryBuilder Integration

findMetadata() and findMetadataById() combine data fetching and metadata generation in a single call. depth: 1 is applied automatically.

// Find by query → Metadata | null (limit: 1 auto-applied)
export async function generateMetadata({ params }): Promise<Metadata> {
  return await client.from('products').findMetadata(
    { where: { slug: { equals: params.slug } } },
    { siteName: 'My Store' },
  ) ?? {}
}

// Find by ID → Metadata (throws on 404)
const metadata = await client.from('products').findMetadataById(id, {
  siteName: 'My Store',
})

Available on both BrowserClient and ServerClient.

Depth Requirement

Fetch with depth: 1 or higher so the meta.image relation is populated as a full object. At depth 0, only the image ID is returned and OG image will be omitted. findMetadata()/findMetadataById() apply depth: 1 automatically.

// depth: 1 — image is populated
const product = await client.from('products').findById(id, { depth: 1 })

// depth: 0 — image is just a number, OG image omitted
const product = await client.from('products').findById(id, { depth: 0 })

On this page