JSPM

@flightdev/seo

0.2.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 12
  • Score
    100M100P100Q32313F
  • License MIT

Native SEO and head management for Flight Framework. Meta tags, Open Graph, Twitter Cards, JSON-LD, sitemap, and robots.txt generation.

Package Exports

  • @flightdev/seo
  • @flightdev/seo/angular
  • @flightdev/seo/json-ld
  • @flightdev/seo/qwik
  • @flightdev/seo/react
  • @flightdev/seo/robots
  • @flightdev/seo/sitemap
  • @flightdev/seo/solid
  • @flightdev/seo/svelte
  • @flightdev/seo/vue

Readme

@flightdev/seo

Native SEO and head management for Flight Framework. Zero dependencies, framework-agnostic, SSR-first.

Features

  • Head Management - Tag deduplication, ordering, and efficient rendering
  • Meta Tags - Basic meta, robots, verification, viewport
  • Open Graph - Full OG protocol support including article, product, profile
  • Twitter Cards - Summary, large image, app, and player cards
  • JSON-LD - Type-safe structured data for rich results
  • Sitemap Generation - XML sitemaps with image, video, and news support
  • robots.txt - Configurable crawler directives
  • Framework Integrations - React, Vue, Solid, Svelte

Installation

npm install @flightdev/seo

Quick Start

Core API

import { createSEO, defineMeta } from '@flightdev/seo';

const seo = createSEO({
    baseUrl: 'https://example.com',
    titleTemplate: '%s | My Site',
    defaultTitle: 'My Site',
});

const metadata = defineMeta({
    title: 'About Us',
    description: 'Learn more about our company',
    canonical: '/about',
    openGraph: {
        type: 'website',
        images: [{ url: '/og.jpg', width: 1200, height: 630 }],
    },
    twitter: {
        card: 'summary_large_image',
    },
});

const { html, tags } = seo.render(metadata);
// Insert `html` into your document head

React

import { SEO, JsonLd } from '@flightdev/seo/react';

export default function ProductPage({ product }) {
    return (
        <>
            <SEO
                title={product.name}
                description={product.description}
                openGraph={{
                    type: 'product',
                    images: [{ url: product.image }],
                }}
            />
            <JsonLd
                data={{
                    '@type': 'Product',
                    name: product.name,
                    offers: {
                        '@type': 'Offer',
                        price: product.price,
                        priceCurrency: 'USD',
                    },
                }}
            />
            <main>{/* Page content */}</main>
        </>
    );
}

Vue

<script setup>
import { useSEO, useJsonLd } from '@flightdev/seo/vue';

const product = defineProps(['product']);

useSEO({
    title: product.name,
    description: product.description,
    openGraph: {
        type: 'product',
        images: [{ url: product.image }],
    },
});

useJsonLd({
    '@type': 'Product',
    name: product.name,
    offers: {
        '@type': 'Offer',
        price: product.price,
        priceCurrency: 'USD',
    },
});
</script>

Solid

import { SEO, JsonLd } from '@flightdev/seo/solid';

export default function ProductPage(props) {
    return (
        <>
            <SEO
                title={props.product.name}
                description={props.product.description}
            />
            <JsonLd data={{ '@type': 'Product', name: props.product.name }} />
            <main>...</main>
        </>
    );
}

Svelte

<script>
    import { generateMetadataHtml, createJsonLdScript } from '@flightdev/seo/svelte';

    export let product;
</script>

<svelte:head>
    {@html generateMetadataHtml({
        title: product.name,
        description: product.description,
        openGraph: { type: 'product' }
    })}
    {@html createJsonLdScript({
        '@type': 'Product',
        name: product.name
    })}
</svelte:head>

API Reference

createSEO(config?)

Create an SEO service instance.

const seo = createSEO({
    baseUrl: 'https://example.com',
    titleTemplate: '%s | My Site',
    defaultTitle: 'My Site',
    defaultOpenGraph: {
        siteName: 'My Site',
        locale: 'en_US',
    },
    defaultTwitter: {
        site: '@mysite',
    },
});

defineMeta(metadata)

Type-safe metadata definition.

const metadata = defineMeta({
    title: 'Page Title',
    description: 'Page description',
    keywords: ['keyword1', 'keyword2'],
    author: 'Author Name',
    canonical: 'https://example.com/page',
    robots: { index: true, follow: true },
    openGraph: { /* ... */ },
    twitter: { /* ... */ },
});

Metadata Types

interface Metadata {
    // Basic
    title?: string;
    titleTemplate?: string;
    description?: string;
    keywords?: string | string[];
    author?: string;
    canonical?: string;

    // Robots
    robots?: RobotsMeta | string;
    googleBot?: RobotsMeta | string;

    // Open Graph
    openGraph?: {
        type?: 'website' | 'article' | 'product' | ...;
        title?: string;
        description?: string;
        url?: string;
        siteName?: string;
        locale?: string;
        images?: OpenGraphImage[];
        article?: OpenGraphArticle;
        product?: OpenGraphProduct;
    };

    // Twitter
    twitter?: {
        card?: 'summary' | 'summary_large_image' | 'app' | 'player';
        title?: string;
        description?: string;
        site?: string;
        creator?: string;
        image?: TwitterCardImage | string;
    };
}

JSON-LD Structured Data

import {
    createJsonLd,
    articleJsonLd,
    productJsonLd,
    breadcrumbJsonLd,
    faqJsonLd,
} from '@flightdev/seo/json-ld';

// Generic
const jsonLd = createJsonLd({
    '@type': 'Organization',
    name: 'My Company',
    url: 'https://example.com',
});

// Article
const article = articleJsonLd({
    headline: 'Article Title',
    datePublished: '2026-01-10',
    author: { '@type': 'Person', name: 'Author' },
    publisher: { '@type': 'Organization', name: 'Publisher' },
});

// Product
const product = productJsonLd({
    name: 'Widget',
    description: 'A great widget',
    offers: {
        '@type': 'Offer',
        price: 9.99,
        priceCurrency: 'USD',
        availability: 'InStock',
    },
});

// Breadcrumb
const breadcrumb = breadcrumbJsonLd([
    { name: 'Home', url: '/' },
    { name: 'Products', url: '/products' },
    { name: 'Widget' },
]);

// FAQ
const faq = faqJsonLd([
    { question: 'What is this?', answer: 'A great product.' },
    { question: 'How much?', answer: '$9.99' },
]);

Sitemap Generation

import { createSitemap, createSitemapIndex } from '@flightdev/seo/sitemap';

const sitemap = createSitemap({
    baseUrl: 'https://example.com',
    pretty: true,
});

// Add URLs
sitemap.add('/', { priority: 1.0, changefreq: 'daily' });
sitemap.add('/about', { priority: 0.8 });
sitemap.add('/products/widget', {
    lastmod: new Date(),
    priority: 0.7,
    images: [{ loc: '/images/widget.jpg', title: 'Widget' }],
});

// Generate XML
const xml = sitemap.generate();

// For large sites, use sitemap index
const index = createSitemapIndex();
index.add('https://example.com/sitemap-1.xml');
index.add('https://example.com/sitemap-2.xml');
const indexXml = index.generate();

robots.txt Generation

import { createRobots, standardRobots } from '@flightdev/seo/robots';

// Custom
const robots = createRobots();
robots.allow('*', '/');
robots.disallow('*', '/admin');
robots.disallow('*', '/api');
robots.addSitemap('https://example.com/sitemap.xml');
const txt = robots.generate();

// Standard preset
const standard = standardRobots({
    sitemapUrl: 'https://example.com/sitemap.xml',
    blockPaths: ['/private'],
});

SSR Integration

// In your server entry
import { createSEO, createHeadManager } from '@flightdev/seo';

const seo = createSEO({ baseUrl: 'https://example.com' });

export function render(url: string, metadata: Metadata): string {
    const { html: headHtml } = seo.render(metadata);

    return `
<!DOCTYPE html>
<html>
<head>
    ${headHtml}
</head>
<body>
    <!-- app content -->
</body>
</html>
    `;
}

Dynamic Metadata

// src/routes/products/[id].page.tsx
import { defineMeta } from '@flightdev/seo';

export async function generateMetadata({ params }) {
    const product = await getProduct(params.id);

    return defineMeta({
        title: product.name,
        description: product.description,
        openGraph: {
            type: 'product',
            images: [{ url: product.image }],
        },
    });
}

export default function ProductPage({ product }) {
    return <main>{/* content */}</main>;
}

Best Practices

  1. Always set title and description - These are essential for SEO
  2. Use canonical URLs - Prevent duplicate content issues
  3. Provide Open Graph images - 1200x630px recommended for social sharing
  4. Add structured data - Improves rich results in search
  5. Generate sitemaps - Help search engines discover your pages
  6. Configure robots.txt - Control crawler access

License

MIT License