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
| Option | Type | Description |
|---|---|---|
title | string | Fallback title |
description | string | Fallback description |
siteName | string | og: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 })