@coffeecup_tech/docusaurus-plugin-structured-data
v1.0.2
Published
Docusaurus plugin to generate JSON-LD structured data (schema.org) for SEO
Maintainers
Readme
Docusaurus plugin to generate JSON-LD structured data (schema.org) for SEO
A Docusaurus plugin that automatically generates JSON-LD structured data (schema.org) for your documentation site's SEO. This plugin scans your markdown/MDX files for front matter schema definitions and generates a React Root component that injects the appropriate structured data into each page.
Features
- 🎯 Automatic Schema Generation: Extracts schema definitions from markdown front matter
- 🌐 JSON-LD Output: Generates valid schema.org JSON-LD for SEO
- 🌍 i18n Support: Handles multilingual sites with locale-specific schemas
- ⚙️ Configurable Paths: Support for custom directory structures
- 🔍 Multiple Schema Types: Support for Article, BlogPosting, Organization, Person, Service, and more
- 🛡️ Error Handling: Graceful error handling and recovery
- 🧪 Fully Tested: Comprehensive Jest test suite with 14+ tests
- 📝 Verbose Logging: Optional detailed logging for debugging
- 🔧 TypeScript: Fully typed with TypeScript interfaces
Installation
npm install @coffeecup_tech/docusaurus-plugin-structured-dataor with yarn:
yarn add @coffeecup_tech/docusaurus-plugin-structured-dataConfiguration
Add the plugin to your docusaurus.config.js:
module.exports = {
// ... other config
plugins: [
[
'@coffeecup_tech/docusaurus-plugin-structured-data',
{
// Optional: Enable verbose logging
verbose: false,
// Optional: Custom directory paths (relative to siteDir)
srcDir: 'src/pages',
blogDir: 'blog',
docsDir: 'docs',
// Optional: Custom output path for Root.js
outputFile: 'src/theme/Root.js',
// Optional: Fallback image URL for schemas without images
defaultImage: 'https://example.com/default-image.png',
// Base schema for organization/person/website (optional)
baseSchema: {
organization: {
'@id': '${DOCUSAURUS_CONFIG_URL}/#organization',
'@type': 'Organization',
name: 'My Organization',
url: '${DOCUSAURUS_CONFIG_URL}',
logo: '${DOCUSAURUS_CONFIG_URL}/logo.png',
sameAs: '${SAME_AS_DEFAULT}',
},
person: {
'@id': '${DOCUSAURUS_CONFIG_URL}/#person',
'@type': 'Person',
name: 'John Doe',
},
website: {
'@id': '${DOCUSAURUS_CONFIG_URL}/#website',
'@type': 'WebSite',
name: 'My Website',
url: '${DOCUSAURUS_CONFIG_URL}',
},
},
// Optional: i18n specific schemas
i18n: {
fr: {
baseSchema: {
organization: {
'@id': '${DOCUSAURUS_CONFIG_URL}/#organization',
'@type': 'Organization',
name: 'Mon Organisation',
},
},
},
},
// Optional: sameAs default values
sameAsDefault: [
'https://twitter.com/example',
'https://github.com/example',
],
},
],
],
};Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| verbose | boolean | false | Enable verbose logging during generation |
| srcDir | string | 'src/pages' | Path to pages directory (relative to siteDir) |
| blogDir | string | 'blog' | Path to blog directory (relative to siteDir) |
| docsDir | string | 'docs' | Path to docs directory (relative to siteDir) |
| outputFile | string | 'src/theme/Root.js' | Path where Root.js will be written |
| defaultImage | string | undefined | Fallback image URL for schemas without images |
| baseSchema | object | undefined | Organization/person/website schema structure |
| i18n | object | undefined | Locale-specific schema overrides |
| sameAsDefault | array | [] | Default sameAs URLs for organization |
Usage
Adding Schema to Your Content
Add a schema object to the front matter of your markdown/MDX files:
---
title: My Blog Post
slug: my-blog-post
description: This is a great blog post
image: /img/my-image.png
date: 2024-01-15
schema:
type: BlogPosting
headline: My Blog Post
description: This is a great blog post
image: /img/my-image.png
datePublished: 2024-01-15
dateModified: 2024-01-15
---
# My Blog Post
Content here...Supported Schema Types
The plugin automatically enriches the following schema.org types:
- Article - General articles with author/publisher
- BlogPosting - Blog posts with author/publisher
- CollectionPage - Pages that collect other content
- Blog - Blog containers
- AboutPage - About pages
- Service - Services with provider reference
- WebSite - Website metadata
- Organization - Organization information
- Person - Person information
Running the Generator
The plugin registers a CLI command with Docusaurus:
npx docusaurus generate-structured-dataThis command:
- Scans all markdown/MDX files in configured directories
- Extracts schema definitions from front matter
- Generates a Root.js component with JSON-LD structured data
- Writes the Root.js file to the specified output path
Automatic Enrichment
The plugin automatically adds:
- URL: Current page URL
- mainEntityOfPage: WebPage reference for the current page
- author/publisher: Organization and person references (for Article types)
- provider: Organization reference (for Service types)
- inLanguage: Current locale or 'en-US'
Development
Build
npm run buildCompiles TypeScript from src/ to lib/ directory.
Watch Mode
npm run watchAutomatically recompiles on file changes.
Testing
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coverageThe test suite includes:
- Core Functionality Tests: Directory creation, file generation, configuration
- Error Handling Tests: Permission errors, write failures, missing configs
- Schema Generation Tests: JSON-LD validation, type handling, i18n support
Git Workflow
A pre-commit hook is configured with Husky to automatically run npm run build before each commit. This ensures the compiled lib/ directory stays in sync with source code.
Simply commit as usual:
git add src/
git commit -m "Your message"
# npm run build runs automaticallyExamples
Example 1: Blog Post with Full Metadata
---
title: Getting Started with Docusaurus
slug: getting-started-docusaurus
description: A comprehensive guide to setting up Docusaurus
image: /img/docusaurus-hero.png
date: 2024-01-10
schema:
type: BlogPosting
headline: Getting Started with Docusaurus
description: A comprehensive guide to setting up Docusaurus
image: /img/docusaurus-hero.png
datePublished: 2024-01-10
dateModified: 2024-01-15
---
# Getting Started with Docusaurus
Your content here...Example 2: Documentation Page
---
title: API Reference
description: Complete API documentation
schema:
type: Article
headline: API Reference
description: Complete API documentation
---
# API Reference
Documentation content...Example 3: With i18n
French version (i18n/fr/...):
---
title: Commencer avec Docusaurus
schema:
type: BlogPosting
headline: Commencer avec Docusaurus
description: Un guide complet pour configurer Docusaurus
---
# Commencer avec Docusaurus
Contenu ici...With the i18n configuration, the plugin will use French-specific schema and locale in the generated JSON-LD.
Architecture
Core Flow
- Plugin Entry (
src/index.ts): Registers the CLI command - Generator (
src/generator.ts): Main logic that:- Scans markdown/MDX files in docs, blog, and src/pages
- Extracts front matter schema definitions
- Generates a React Root component
- Injects JSON-LD
<script type="application/ld+json">tags
Generated Root Component
The plugin generates a React Root component that:
- Uses the Docusaurus router to get the current page URL
- Looks up schema data for the current path
- Enriches the schema with site-wide metadata
- Injects JSON-LD structured data into the page head
Error Handling
The plugin includes robust error handling:
- Missing Directories: Gracefully skips missing source directories
- File Read Errors: Logs errors and continues processing other files
- Directory Creation: Automatically creates the output directory if missing
- Write Errors: Throws clear error messages if the output file cannot be written
All errors are logged appropriately based on the verbose flag.
Performance Considerations
- The plugin scans directories only during generation (not at runtime)
- The generated Root.js is optimized for performance
- JSON-LD data is embedded directly in the page (no additional requests)
- i18n locales are handled efficiently with minimal data duplication
Troubleshooting
No schema data is being generated
- Check that your front matter has a
schemaobject - Verify the file is
.mdor.mdx - Ensure the file is in the scanned directories (src/pages, blog, docs)
- Run with
verbose: trueto see detailed logging
Routes are not generating schema
- Verify the
schema.typeis in the supported list - Check that the file path matches the generated route
- Ensure i18n locales are correctly configured
Permission errors on build
- Ensure the output directory is writable
- Check file permissions on the output location
- Verify disk space is available
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT
