Skip to content

Repository files navigation

seo-engine Logo

seo-engine

npm version License

A lightweight, framework-agnostic TypeScript library for generating SEO metadata, Open Graph data, Twitter Cards, structured data, and HTML output from a single configuration object.

Generate consistent SEO data with sensible defaults, extensible plugins, configurable schema builders, and optional SEO scoring.

📦 Available on npm: https://www.npmjs.com/package/seo-engine


✨ Features

  • 🚀 Framework-agnostic
  • 📝 TypeScript-first API
  • 🪶 Zero runtime dependencies
  • 🔌 Extensible plugin system
  • 🏗️ Configurable schema builders
  • 🌐 Open Graph support
  • 🐦 Twitter Card support
  • 📄 Canonical URL generation
  • 🧩 JSON-LD structured data
  • ✨ Sensible defaults and fallbacks
  • 📊 Optional SEO scoring
  • 🧪 Fully tested and designed for extensibility

📦 Installation

npm install seo-engine

Requirements

  • Node.js >= 20
  • TypeScript support included

🚀 Quick Start

import { createSeoEngine } from "seo-engine";

const seo = createSeoEngine({
  siteName: "My App",
});

const result = seo.generate({
  title: "Home",
  description: "Welcome to my website",
  url: "https://example.com",
});

console.log(result);

The generated result contains:

{
  title,
  meta,
  link,
  openGraph,
  twitter,
  structuredData,
  html,
}

🌐 Framework Compatibility

seo-engine is framework-agnostic and works with any JavaScript or TypeScript application.

It can be used with:

  • Vanilla JavaScript / TypeScript
  • React / Next.js
  • Vue / Nuxt
  • Angular
  • Other JavaScript and TypeScript frameworks

The engine focuses on generating SEO data. Framework-specific libraries can handle injecting the generated data into the document head.

Vanilla JavaScript Example

import { createSeoEngine } from "seo-engine";

const seo = createSeoEngine();

const result = seo.generate({
  title: "Home",
  description: "Welcome to my website",
});

document.title = result.title;

Next.js Example

import { createSeoEngine } from "seo-engine";

const seo = createSeoEngine({
  siteName: "My App",
});

export function generateMetadata() {
  const result = seo.generate({
    title: "Home",
    description: "Welcome to my website",
    image: "https://example.com/image.png",
  });

  return {
    title: result.title,
    description: result.meta.description,
    openGraph: result.openGraph,
    twitter: result.twitter,
  };
}

Nuxt Example

Nuxt can consume generated metadata using useSeoMeta and structured data using useHead.

import { createSeoEngine } from "seo-engine";

const seo = createSeoEngine({
  siteName: "My App",
});

const result = seo.generate({
  title: "Home",
  description: "Welcome to my website",
  url: "https://example.com",
});

useSeoMeta({
  title: result.title,
  description: result.meta.description,
  ogTitle: result.openGraph["og:title"],
  ogDescription: result.openGraph["og:description"],
  twitterCard: result.twitter["twitter:card"],
});

useHead({
  script: [
    {
      type: "application/ld+json",
      children: JSON.stringify(result.structuredData),
    },
  ],
});

React Example

import { createSeoEngine } from "seo-engine";

const seo = createSeoEngine({
  siteName: "My App",
});

const result = seo.generate({
  title: "Home",
  description: "Welcome to my website",
});

// Pass generated SEO data to your preferred React head management solution.

Angular Example

Angular applications can use the generated SEO data with Angular's built-in Title and Meta services.

import { Title, Meta } from "@angular/platform-browser";
import { createSeoEngine } from "seo-engine";

const seo = createSeoEngine({
  siteName: "My App",
});

const result = seo.generate({
  title: "Home",
  description: "Welcome to my website",
});

// Inside an Angular component/service:
titleService.setTitle(result.title);

metaService.updateTag({
  name: "description",
  content: result.meta.description ?? "",
});

⚙️ Configuration

import { createSeoEngine } from "seo-engine";

const seo = createSeoEngine({
  siteName: "My App",
  locale: "en_US",
  twitterCard: "summary_large_image",
  debug: true,
});

Available options:

Option Description
siteName Default website name
locale Default locale for metadata
twitterCard Twitter Card type
plugins Custom SEO plugins
schemaType Built-in schema type
schemaBuilder Custom JSON-LD builder
debug Enables debug information and SEO scoring

📄 Generating SEO Data

The engine accepts a simple DTO:

const result = seo.generate({
  title: "About Us",
  description: "Learn more about our company",
  url: "https://example.com/about",
  image: "https://example.com/image.png",
});

title is required.

Other fields are optional and can be generated or extended through plugins and fallbacks.


🔌 Plugins

Plugins allow you to customize the SEO generation pipeline.

A plugin can:

  • modify input before generation
  • modify output after generation
  • add custom SEO processing rules

Example:

import type { SeoPlugin } from "seo-engine";

const titleCleaner: SeoPlugin = {
  name: "title-cleaner",

  beforeGenerate(dto) {
    return {
      ...dto,
      title: dto.title.trim(),
    };
  },
};

Register the plugin:

const seo = createSeoEngine({
  plugins: [titleCleaner],
});

Plugins can also define execution order using priority:

const plugin: SeoPlugin = {
  name: "example-plugin",
  priority: 10,

  afterGenerate(result) {
    return result;
  },
};

Plugin Factories

For reusable and configurable plugins, you can create a factory function that returns a SeoPlugin.

Example:

import type { SeoPlugin } from "seo-engine";

const createTitleCleaner = (options: { maxLength: number }): SeoPlugin => ({
  name: "title-cleaner",

  beforeGenerate(dto) {
    return {
      ...dto,
      title: dto.title.slice(0, options.maxLength),
    };
  },
});

Use the plugin factory:

const seo = createSeoEngine({
  plugins: [
    createTitleCleaner({
      maxLength: 60,
    }),
  ],
});

Plugin factories are useful for creating reusable plugins with custom configuration.


🏗️ Custom Schema Builders

Built-in schemas are supported:

  • WebPage
  • Article
  • Organization
  • BreadcrumbList

You can also provide your own JSON-LD schema:

const seo = createSeoEngine({
  schemaBuilder: (dto) => ({
    "@context": "https://schema.org",
    "@type": "WebPage",
    name: dto.title,
  }),
});

📊 SEO Scoring

Enable scoring with:

const seo = createSeoEngine({
  debug: true,
});

The result will include:

result.seoScore;

with:

  • score
  • grade
  • detected issues

⚠️ Error Handling

The engine provides structured errors with predefined error codes:

try {
  seo.generate({
    title: "",
  });
} catch (error) {
  console.log(error.code);
}

Available error codes:

import { ERROR_CODES } from "seo-engine";

ERROR_CODES.INVALID_INPUT;
ERROR_CODES.INVALID_SCHEMA;
ERROR_CODES.GENERATION_FAILED;

📚 API

createSeoEngine(config)

Creates a new SEO engine instance.

generate(dto)

Generates SEO metadata from an SEO DTO.

Exported Types

The package exports:

SeoDTO;
SeoResult;
SeoEngine;
SeoEngineConfig;
SeoPlugin;
SeoPluginFactory;
SeoDefaults;
SchemaBuilder;
SchemaType;

🛣️ Roadmap

  • Additional schema types (FAQPage, Product, etc.)
  • More official plugins
  • Framework adapters
  • Automated release workflows
  • Extended SEO analysis
  • AI-powered SEO suggestions

🤝 Contributing

Contributions, bug reports, feature requests, and improvements are welcome.

Please open an issue or pull request on GitHub with a clear description of the change.


📄 License

MIT © 2026 Farimah Fattahi

About

A lightweight TypeScript SEO metadata generator with Open Graph, Twitter Cards, JSON-LD, and plugin support.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages