diff --git a/.changeset/tidy-routers-arrive.md b/.changeset/tidy-routers-arrive.md
new file mode 100644
index 0000000..0dde980
--- /dev/null
+++ b/.changeset/tidy-routers-arrive.md
@@ -0,0 +1,8 @@
+---
+"@dualmark/remix": minor
+"@dualmark/core": minor
+---
+
+Add React Router v7 Framework Mode adapter with generated markdown resource routes and entry.server negotiation.
+
+Add shared bot-aware content negotiation that respects explicit Accept preferences.
diff --git a/README.md b/README.md
index bbacdda..cb67e12 100644
--- a/README.md
+++ b/README.md
@@ -140,6 +140,42 @@ Full example with `vite dev` → 125/125 conformance score:
[Full SvelteKit example →](./examples/sveltekit-blog)
+### React Router v7 / Remix (60 seconds)
+
+```bash
+bun add @dualmark/remix
+```
+
+```ts
+// vite.config.ts
+import { reactRouter } from "@react-router/dev/vite";
+import { defineConfig } from "vite";
+import dualmark from "@dualmark/remix";
+import dualmarkConfig from "./app/dualmark.config";
+
+export default defineConfig({
+ plugins: [dualmark(dualmarkConfig), reactRouter()],
+});
+```
+
+```ts
+// app/routes.ts
+import { index, route, type RouteConfig } from "@react-router/dev/routes";
+import { dualmarkRoutes } from "@dualmark/remix/routes";
+import dualmarkConfig from "./dualmark.config";
+
+export default [
+ index("routes/home.tsx"),
+ route("posts", "routes/posts.tsx"),
+ route("posts/:slug", "routes/post.tsx"),
+ ...dualmarkRoutes(dualmarkConfig),
+] satisfies RouteConfig;
+```
+
+Full example with `react-router dev` → 125/125 conformance score:
+
+[Full React Router example →](./examples/remix-blog)
+
### Cloudflare Workers (60 seconds)
Wrap your existing Worker. AI bots get markdown at the edge — single-digit-ms first-byte from 300+ cities.
@@ -308,6 +344,7 @@ Three conformance levels — **Basic** (60%), **Standard** (80%), **Advanced** (
| [`@dualmark/converters`](./packages/converters) | `npm i @dualmark/converters` | 16 KB | Production-tested converter factories. |
| [`@dualmark/astro`](./packages/astro) | `npm i @dualmark/astro` | 22 KB | Astro 5 integration. Auto-generates `.md` endpoints, ships middleware, generates `llms.txt`. |
| [`@dualmark/nextjs`](./packages/nextjs) | `npm i @dualmark/nextjs` | 15 KB | Next.js App Router adapter. `withDualmark()`, `createDualmarkMiddleware()`, `createDualmarkRouteHandler()`, `createLlmsTxtHandler()`. |
+| [`@dualmark/remix`](./packages/remix) | `npm i @dualmark/remix` | 12 KB | React Router v7 Framework Mode adapter. Generated markdown resource routes plus `entry.server` negotiation. |
| [`@dualmark/sveltekit`](./packages/sveltekit) | `npm i @dualmark/sveltekit` | 19 KB | SvelteKit adapter. Vite route generator, `createDualmarkHandle()`, generated `.md` endpoints, and `llms.txt`. |
| [`@dualmark/nuxt`](./packages/nuxt) | `npm i @dualmark/nuxt` | 15 KB | Nuxt module. Auto-generates `.md` endpoints, injects `Link rel="alternate"` middleware, generates `llms.txt`. |
| [`@dualmark/cloudflare`](./packages/cloudflare) | `npm i @dualmark/cloudflare` | 9 KB | Workers edge adapter. Wraps any upstream Worker. Hooks for analytics + telemetry. |
@@ -322,7 +359,7 @@ Plus:
- [**`spec/`**](./spec) — the **AEO Specification v1.0**. Public, framework-agnostic, RFC-2119-compliant. Implement it in Go, Rust, PHP, Ruby — your call.
- [**`apps/docs/`**](./apps/docs) — Fumadocs site at [dualmark.dev](https://dualmark.dev)
- [**`apps/docs/app/play`**](./apps/docs/app/play) — interactive Accept-header + UA tester. Live at [dualmark.dev/play](https://dualmark.dev/play).
-- [**`examples/`**](./examples) — ten end-to-end working examples (Astro, Astro+Cloudflare, Sanity+Astro, Next.js, SvelteKit, Nuxt, Deno, Netlify, Fastly, Vercel).
+- [**`examples/`**](./examples) — eleven end-to-end working examples (Astro, Astro+Cloudflare, Sanity+Astro, Next.js, React Router, SvelteKit, Nuxt, Deno, Netlify, Fastly, Vercel).
---
@@ -338,6 +375,7 @@ Plus:
| `@dualmark/cli` | 25 tests pass |
| `@dualmark/astro` | 39 tests pass |
| `@dualmark/nextjs` | 47 tests pass |
+| `@dualmark/remix` | 24 tests pass |
| `@dualmark/sveltekit` | 17 tests pass |
| `@dualmark/nuxt` | 37 tests pass |
| `@dualmark/netlify` | 28 tests pass |
@@ -346,6 +384,7 @@ Plus:
| `examples/sanity-astro` | **80/80** under `astro dev` (`--skip-negotiation`) for fixture-backed blog + glossary docs |
| `examples/astro-cloudflare-full` | **125/125 perfect** under `wrangler dev` (full negotiation) |
| `examples/nextjs-app-router` | **120/125** under `next dev` (now using `@dualmark/nextjs`) |
+| `examples/remix-blog` | **125/125 perfect** under `react-router dev` (`@dualmark/remix`) |
| `examples/sveltekit-blog` | **125/125 perfect** under `vite dev` (full negotiation) |
| `examples/deno-deploy` | **125/125 perfect** under `deno run` (full negotiation) |
| `examples/fastly-compute` | **125/125 perfect** under `fastly compute serve` (full negotiation) |
@@ -364,7 +403,6 @@ bun run build && bun run test && bun run typecheck # 407 tests across 9 packag
We're building toward Dualmark being **the** AEO infrastructure for marketing sites — the same way Tailwind became the default for marketing CSS or Vercel for marketing hosting. The roadmap:
-- **More framework adapters**: Remix/React Router
- **More converters**: pricing tables, changelog, docs/API reference, status pages, integrations
- **AEO Analytics**: a hosted dashboard on top of the `onAIRequest` hook, so marketing can see which bot reads which page, when
- **Spec evolution toward AEO 1.1+** with structured data hints, per-section markdown anchors, and sitemap.md
diff --git a/apps/docs/app/_components/adapters.tsx b/apps/docs/app/_components/adapters.tsx
index 335dbde..06e58b4 100644
--- a/apps/docs/app/_components/adapters.tsx
+++ b/apps/docs/app/_components/adapters.tsx
@@ -6,6 +6,7 @@ import {
NetlifyLogo,
NextLogo,
NuxtLogo,
+ ReactRouterLogo,
SvelteLogo,
VercelLogo,
} from "@/components/brand-logos";
@@ -93,6 +94,16 @@ const adapters: Adapter[] = [
accent: "oklch(0.78 0.17 160)",
Logo: NuxtLogo,
},
+ {
+ name: "React Router",
+ pkg: "@dualmark/remix",
+ desc: "React Router v7 Framework Mode adapter. Generated .md resource routes plus entry.server negotiation.",
+ install: "bun add @dualmark/remix",
+ score: "125/125",
+ status: "Stable",
+ accent: "oklch(0.74 0.18 250)",
+ Logo: ReactRouterLogo,
+ },
{
name: "Deno",
pkg: "@dualmark/deno",
@@ -146,7 +157,7 @@ export function Adapters() {
your stack.
>
}
- description="Nine first-class adapters today. Remix/React Router on the roadmap."
+ description="Ten first-class adapters today. More platform adapters are on the roadmap."
/>
diff --git a/apps/docs/components/brand-logos.tsx b/apps/docs/components/brand-logos.tsx
index 0134541..ac331cc 100644
--- a/apps/docs/components/brand-logos.tsx
+++ b/apps/docs/components/brand-logos.tsx
@@ -132,6 +132,26 @@ export function SvelteLogo({ size = 24, ...props }: LogoProps) {
);
}
+export function ReactRouterLogo({ size = 24, ...props }: LogoProps) {
+ return (
+
+ );
+}
+
export function DenoLogo({ size = 24, ...props }: LogoProps) {
return (