# What Is the badseo Package in OpenSEO? Purpose and Developer Guide

> Explore the badseo package in OpenSEO. Discover its purpose as a test site filled with SEO errors for auditing and development. Learn how to use it effectively.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: deep-dive
- Published: 2026-09-05

---

**The badseo package supplies a self-contained test site (`badseo.dev`) deliberately riddled with common SEO mistakes to act as a regression-test fixture and experimental playground for the OpenSEO audit engine.**

The badseo package is a critical testing infrastructure within the `every-app/open-seo` repository. It hosts a live TanStack Start application deployed as a Cloudflare Worker that renders both healthy pages and intentionally broken SEO fixtures, providing deterministic test data that validates the audit engine's issue-detection capabilities across continuous integration pipelines.

## Architecture and Purpose of the badseo Package

The primary role of the badseo package is to ensure the OpenSEO audit engine remains accurate as the codebase evolves. It achieves this by serving real HTML pages that violate specific SEO rules, then verifying that the engine correctly identifies each violation through an automated harness.

### The badseo.dev Test Site Implementation

At the core of the package is `badseo.dev`, a TanStack Start application deployed as a Cloudflare Worker. According to the source code in [`badseo/src/server/badseo.ts`](https://github.com/every-app/open-seo/blob/main/badseo/src/server/badseo.ts), the application renders a healthy homepage and privacy page for baseline testing, while a catch-all server route serves raw HTML fixtures that intentionally break one SEO rule each.

The server architecture distinguishes between legitimate application routes and test fixtures:

- **Valid pages**: Standard TanStack Start routes for homepage and privacy policy
- **Fixture routes**: A catch-all handler that renders HTML fixtures based on the requested path
- **Crawler discovery**: Endpoints that allow the audit harness to enumerate available test cases

### Comprehensive SEO Issue Coverage

Every issue type detectable by the OpenSEO engine is represented by at least one fixture page. The fixtures are organized into logical categories defined in the source configuration, ensuring complete coverage of the audit registry:

- **Head tags & headings**: Missing or malformed title tags, multiple H1 elements
- **Content quality**: Thin content, duplicate content, keyword stuffing
- **Indexability & canonical**: Incorrect canonical tags, noindex directives, robots.txt conflicts
- **Redirects**: Chains, loops, and improper redirect implementations

Each fixture in `badseo/src/fixtures/*.ts` is a TypeScript object that maps a specific URL path to its expected SEO violations, enabling type-safe validation against the audit engine's issue registry.

## Testing Infrastructure and CI Integration

The badseo package includes a sophisticated end-to-end testing harness that transforms the static fixtures into an active quality gate.

### End-to-End Audit Harness

Located at [`badseo/scripts/run-audit.ts`](https://github.com/every-app/open-seo/blob/main/badseo/scripts/run-audit.ts), the harness executes the *real* OpenSEO crawling and issue-detection functions against a running instance of `badseo.dev`. This script:

1. Crawls the test site using the production audit engine code
2. Compares detected issues against the `expectedIssues` array defined in each fixture
3. Asserts that each fixture triggers exactly the issues it declares
4. Fails CI if any fixture produces unexpected results or misses expected detections

This integration ensures that changes to the audit engine do not introduce regressions in issue detection accuracy.

### Local Development Workflow

Developers can iterate on the audit engine using the badseo package through two primary commands. First, start the test site locally:

```bash
cd badseo
npm run dev   # → http://localhost:8787

```

Then, in a separate terminal, execute the audit harness against the local instance:

```bash
npm run audit -- http://localhost:8787

```

This workflow allows developers to verify that new audit rules correctly detect their corresponding SEO mistakes before submitting changes.

## Creating Custom SEO Test Fixtures

Adding new test cases to the badseo package involves creating a TypeScript fixture definition that the type system validates against the audit registry. Each fixture resides in `badseo/src/fixtures/` and exports a configuration object:

```typescript
// badseo/src/fixtures/my-mistake.ts
const myFixture: Fixture = {
  path: "/category/my-mistake",
  category: "Content quality",
  name: "My SEO mistake",
  summary: "One-line description shown in the on‑page test panel.",
  lesson: "Why it matters / how to fix it.",
  expectedIssues: ["thin-content"],   // audit issue IDs this page must trigger
  handler: () => htmlResponse(
    renderPage({
      fixture: myFixture,
      title: "…",
      metaDescription: "…",
      bodyHtml: "…",
    })
  ),
};

```

The `expectedIssues` array links the fixture to specific issue IDs in the OpenSEO audit registry. When the harness runs, it verifies that crawling this path produces exactly these issue types, ensuring the audit engine correctly identifies the violation.

## Build and Deployment Pipeline

The badseo package uses Vite for bundling, configured in [`badseo/vite.config.ts`](https://github.com/every-app/open-seo/blob/main/badseo/vite.config.ts) to generate both the TanStack Start client bundle and the Cloudflare Worker server bundle. Low-level HTML rendering primitives in [`badseo/src/lib.ts`](https://github.com/every-app/open-seo/blob/main/badseo/src/lib.ts) support the fixture handlers.

Deploy the test site to production using:

```bash
npm run build   # Vite build + TypeScript check

npm run deploy  # Wrangler deploy → badseo.dev

```

The production deployment at `badseo.dev` serves as the canonical reference environment for the audit harness, though developers typically run tests against local instances during development.

## Summary

- The **badseo package** provides a live test site (`badseo.dev`) that intentionally implements common SEO mistakes to validate the OpenSEO audit engine.
- It runs as a **TanStack Start application** on Cloudflare Workers, serving both healthy pages and targeted fixture routes from [`badseo/src/server/badseo.ts`](https://github.com/every-app/open-seo/blob/main/badseo/src/server/badseo.ts).
- The **end-to-end harness** in [`badseo/scripts/run-audit.ts`](https://github.com/every-app/open-seo/blob/main/badseo/scripts/run-audit.ts) executes real audit functions against the test site, ensuring each fixture triggers its expected issues.
- Developers add new test cases by creating **TypeScript fixture definitions** in `badseo/src/fixtures/` with validated `expectedIssues` arrays.
- The package supports **local development** via `npm run dev` and **CI integration** through `npm run audit`, maintaining engine reliability across code changes.

## Frequently Asked Questions

### What technology stack powers the badseo test site?

The badseo package uses **TanStack Start** for the application framework and **Cloudflare Workers** for the runtime environment. The build pipeline uses **Vite** (configured in [`badseo/vite.config.ts`](https://github.com/every-app/open-seo/blob/main/badseo/vite.config.ts)) to bundle both client and server assets. Low-level HTML generation utilities reside in [`badseo/src/lib.ts`](https://github.com/every-app/open-seo/blob/main/badseo/src/lib.ts), providing rendering primitives for the fixture handlers.

### How does the audit harness validate OpenSEO's detection accuracy?

The harness located at [`badseo/scripts/run-audit.ts`](https://github.com/every-app/open-seo/blob/main/badseo/scripts/run-audit.ts) executes the production OpenSEO crawling logic against a running instance of `badseo.dev`. It compares the issues detected on each fixture page against the `expectedIssues` defined in the fixture's TypeScript configuration. If the detected issues match the expected set exactly, the test passes; any discrepancy fails the CI pipeline.

### Can I contribute new SEO mistake fixtures to the badseo package?

Yes. Contributors can add new fixtures by creating TypeScript files in `badseo/src/fixtures/` that export a `Fixture` object. The configuration must specify the URL path, issue category, human-readable metadata, and an array of `expectedIssues` that map to the audit registry. The type system validates the fixture against the engine's issue definitions, ensuring only valid issue IDs are specified.

### Is badseo.dev publicly accessible for testing?

The test site deploys to `badseo.dev` via Wrangler when maintainers run `npm run deploy`. However, the primary use case involves running the site locally with `npm run dev` and testing against `http://localhost:8787`. This local-first approach allows developers to test audit engine changes without affecting the public deployment or requiring internet connectivity.