Structured Data Generator payload plugin (bundled with tsup)
npm install @sparrowengg/payloadcms-plugin-structured-data-generatorInternal Payload CMS plugin of SurveySparrow for generating Structured Data using AI.
This package has the following peer dependencies. Make sure you have these:
``json`
"payload": "^3.59.1",
"@payloadcms/ui": "^3.59.1"
`bash`
pnpm add @sparrowengg/payloadcms-plugin-structured-data-generator
In your .env file, add the following environment variables:
`env`
NEXT_PUBLIC_SERVER_URL=https://www.yoursite.com
NEXT_PUBLIC_AI_STRUCTURED_DATA_API=
The plugin makes use of Payload's server-side lexical-markdown conversion helper.
Add the following route handlers under app/(payload)/api/ folder:
#### /api/convert-lexical-to-markdown/route.ts
`typescript
import config from '@payload-config';
import { convertLexicalToMarkdown } from '@payloadcms/richtext-lexical';
import type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';
export async function POST(request: Request) {
const data: SerializedEditorState = await request.json();
const editorConfig = ((await config).editor as any)?.editorConfig || {};
const markdown = convertLexicalToMarkdown({
data,
editorConfig,
});
return new Response(JSON.stringify(markdown));
}
`
Create a field name mapping file at /payload/plugins/config/structuredDataGenerator/fieldNameMappings.ts to assign the correct fields for api payload.
`typescript`
export const fieldNameMappings = {
common: {
metaDescription: 'meta.description', // Use dot operator for nested paths
name: 'populatedAuthors[0].name',
publishedAt: 'publishedAt',
},
individualCollections: { // Optional - no need to add this if field names are 'title' & 'content' (example below)
// blogs: {
// title: 'title',
// blogContent: 'content',
// },
'sales-glossary': { // Add this if your title & content field names are different
title: 'glossaryName',
blogContent: 'glossaryContent',
},
}
Import and register the plugin in your Payload config:
`typescript
import { buildConfig } from 'payload/config';
import { structuredDataGenerator } from '@sparrowengg/payloadcms-plugin-structured-data-generator';
import { fieldNameMappings } from './config/structuredDataGenerator/fieldNameMappings';
export default buildConfig({
plugins: [
structuredDataGenerator({
fieldName: 'structuredData',
fieldPath: 'meta.structuredData',
apiUrl: process.env.NEXT_PUBLIC_AI_STRUCTURED_DATA_API ?? '',
fieldNameMappings: fieldNameMappings,
org: 'SparrowGenie', // Use your product
logoUrl: ${process.env.NEXT_PUBLIC_IMAGE_BASE_URL}/meta/sparrowgenie-logo.svg, // Use your product logo`
}),
],
// ... rest of your config
});
Add structuredData field in required collections/globals.
`typescript`
{
// Existing code
name: 'meta',
label: 'SEO',
fields: [
MetaTitleField({
hasGenerateFn: true,
}),
MetaDescriptionField({}),
// Add this field
{
name: 'structuredData',
type: 'json',
},
]
}
`bash`
pnpm payload generate:importmap
Add the Structured Data reusable component in components folder.
`typescript
import Script from 'next/script';
export function StructuredData({ jsonLd }) {
if (!jsonLd) {
return null;
}
return (
id="schema-structured-data"
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(jsonLd),
}}
strategy="lazyOnload"
/>
);
}
`
In whichever page you want this, in the page.jsx file use this component and pass the structured data from Payload CMS to it.
`typescript``
import { StructuredData } from '@/components/scripts/structured-data';
/// const cmsData = fetch cms page data
- Widget will appear below the structured data field on frontend.
- Start interlinking using the button.
- Use the 'Verify' link to copy paste and verify the structured data.