How OpenSEO Handles SEO Configuration: A Technical Deep Dive into the every-app/open-seo Library

OpenSEO centralizes all SEO metadata generation in a TypeScript utility file at web/src/lib/seo.ts, using a buildPageSeo function that transforms declarative configuration objects into canonical URLs, HTML meta tags, Open Graph properties, and Twitter Card data.

The every-app/open-seo repository implements a type-safe, environment-driven approach to SEO management in React applications. By consolidating URL normalization and meta tag generation into reusable helpers, the library ensures consistent SEO patterns across marketing pages, static content, and dynamic routes. Understanding how open-seo handles SEO configuration reveals a pattern that keeps markup declarative while supporting server-side rendering requirements.

Centralized SEO Utilities in web/src/lib/seo.ts

The core SEO logic resides in web/src/lib/seo.ts, which exports a suite of utilities for URL management and metadata construction. This file eliminates hardcoded domain strings and duplicate path logic across the application.

Environment-Driven Site URL Configuration

The library derives the canonical domain from environment variables, prioritizing process.env.SITE_URL or falling back to process.env.VITE_SITE_URL. If neither variable is present, it defaults to https://openseo.so. The SITE_URL constant is automatically trimmed of trailing slashes to prevent double-slash errors when concatenating paths.

Canonical URL Normalization

Two specialized helpers manage URL consistency:

  • toCanonicalPath – Normalizes any path string by ensuring a leading forward slash and removing duplicate trailing slashes.
  • toCanonicalUrl – Combines the normalized path with SITE_URL to generate absolute canonical URLs for use in <link rel="canonical"> tags and Open Graph metadata.

The buildPageSeo Function: Declarative Metadata Generation

The primary interface for page-level SEO is the buildPageSeo function, which accepts a configuration object containing title, path, and optional parameters including description, titleSuffix, ogType, and imageAlt.

According to the source code, the function returns a structured object with two arrays:

  • meta – An array of tag definitions covering standard HTML meta tags, Open Graph (og:title, og:url, etc.), and Twitter Card properties. The function automatically appends a default social card image (/social-card.png) and sets sensible defaults for Open Graph type (website) and image alt text.
  • links – An array containing the canonical link tag pointing to the fully resolved URL.

Page components import this utility and spread the returned arrays into their <Head> or equivalent meta-rendering component, ensuring tags are rendered on the server.

Real-World Implementation Examples

Marketing Pages with Custom Metadata

Dynamic marketing landing pages utilize the full buildPageSeo API to inject branded titles and rich descriptions. The implementation imports the utility from @/lib/seo and maps the returned arrays to JSX elements:

import { buildPageSeo, SITE_URL } from "@/lib/seo";

export const Route = createFileRoute("/_marketing")({
  component: () => {
    const seo = buildPageSeo({
      title: "OpenSEO – All‑in‑One SEO Platform",
      path: "/_marketing",
      description:
        "Boost your search rankings with keyword research, rank tracking, and site audits—all in one place.",
      titleSuffix: "OpenSEO",
    });

    return (
      <>
        <Head>
          {seo.meta.map((tag, i) => {
            if (tag.title) return <title key={i}>{tag.title}</title>;
            if (tag.name)
              return <meta key={i} name={tag.name} content={tag.content} />;
            return (
              <meta
                key={i}
                property={tag.property}
                content={tag.content}
              />
            );
          })}
          {seo.links.map((link, i) => (
            <link key={i} rel={link.rel} href={link.href} />
          ))}
        </Head>
        <MarketingLanding />
      </>
    );
  },
});

Static Pages with Default Patterns

Static content pages like "Terms & Conditions" follow the same pattern with minimal configuration, as seen in web/src/routes/terms-and-conditions.tsx:

import { buildPageSeo } from "@/lib/seo";

export const Route = createFileRoute("/terms-and-conditions")({
  component: () => {
    const seo = buildPageSeo({
      title: "Terms & Conditions",
      path: "/terms-and-conditions",
      description: "Read the terms of service for using OpenSEO.",
    });

    return (
      <>
        <Head>{/* Render seo.meta & seo.links */}</Head>
        <TermsAndConditions />
      </>
    );
  },
});

Summary

  • OpenSEO consolidates SEO logic in web/src/lib/seo.ts, exporting buildPageSeo, toCanonicalPath, and toCanonicalUrl for type-safe metadata management.
  • Environment variables drive the site URL, with automatic fallback handling and trailing slash normalization to ensure valid canonical links.
  • Declarative configuration allows developers to define page titles, descriptions, and Open Graph data through a single function call that returns render-ready meta and link arrays.
  • Consistent implementation patterns appear across marketing and static pages in routes like web/src/routes/_marketing/index.tsx and web/src/routes/terms-and-conditions.tsx.

Frequently Asked Questions

The library checks process.env.SITE_URL first, then process.env.VITE_SITE_URL, defaulting to https://openseo.so if neither environment variable is set. This value is stored in the SITE_URL constant and sanitized to remove trailing slashes before use in URL construction.

What parameters does the buildPageSeo function accept?

The function requires title and path parameters, with optional overrides for description, titleSuffix, ogType, and imageAlt. It automatically generates a default social card image path and Open Graph type when custom values are not provided.

How are canonical URLs generated in the OpenSEO library?

The toCanonicalPath helper normalizes the input path to ensure a leading slash, while toCanonicalUrl combines this normalized path with the SITE_URL environment variable to produce absolute URLs. These are injected into the <link rel="canonical"> tag via the links array returned by buildPageSeo.

Can individual pages override the default social card image in OpenSEO?

Yes, while buildPageSeo provides a default image path of /social-card.png, the implementation supports custom Open Graph images through the configuration object. Each page component can pass custom ogType and imageAlt values to tailor social sharing previews for specific content.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →