# route.bible Integration Skill

This document is for coding agents and developers who are modifying another app to adopt `route.bible`.

Goal: add portable scripture links with the smallest correct integration.

If the goal is simply to make an AI agent link Scripture references by default, install **Bible Links by route.bible** instead of hand-writing instructions:

```sh
npx skills add dpshde/bible-links --skill bible-links
```

- Source: `https://github.com/dpshde/bible-links`
- Skills.sh: `https://skills.sh/dpshde/bible-links/bible-links`

## What `route.bible` is

`route.bible` is a canonical URL and routing layer for Bible passages.

- It gives apps, sites, churches, and tools one durable passage URL format.
- It is not a Bible app and does not replace your app's core reading experience.
- It is most useful when your app needs outbound scripture links, QR/share portability, or app-agnostic fallback behavior.

Use `route.bible` when your app should hand a passage off in a way that can still work across different installed apps, browsers, and devices.

## Core `route.bible` contract at a glance

### 1. Stable URL contract

Published links use lowercase OSIS book codes in the path and stay stable once shared.

Examples:

- `https://route.bible/jhn.3.16`
- `https://route.bible/jhn.3.16-jhn.3.18`
- Book code reference: `https://route.bible/osis.json`

### 2. Parse-friendly input

`?q=<ref>` accepts human input and redirects into the canonical route.

Examples:

- `https://route.bible/?q=John%203%3A16`
- `https://route.bible/?q=1%20Cor%2013%3A4-7`

### 3. Fallback-first resolution

`?app=<id>` can hint a preferred destination, while the launcher and web reader remain the fallback path.

Examples:

- `https://route.bible/jhn.3.16?app=logos`
- Adapter id reference: `https://route.bible/adapters.txt`

### 4. Licensing-aware routing

`?v=<translation>` routes restricted translations to licensed destinations instead of assuming route.bible will host that text directly.

Examples:

- `https://route.bible/jhn.3.16?v=BSB`
- `https://route.bible/jhn.3.16?v=ESV`

## What `route.bible` links are for

Use `route.bible` links to:

- publish one stable scripture URL instead of provider-specific links
- make QR codes and copied links portable
- let users open a passage in their preferred destination when possible
- preserve a clean web fallback when a specific app is not installed
- normalize passage handoff across notes, articles, study tools, slides, exports, and share flows

Do not use `route.bible` to replace internal navigation that should stay inside your own app. If your app is itself the primary reading experience, keep your in-app route for the main flow and add `route.bible` as the portable outbound/share/export surface.

## Choose the smallest integration path

### 1. Your app already parses Bible references

Emit canonical `route.bible` links directly.

This is the best option when your app already knows the passage and only needs a durable outbound URL.

### 2. Your app needs local scripture parsing

Use `grab-bcv`.

This is the best option when your app needs to detect or normalize references from user input, notes, articles, imported text, transcripts, or pasted links before generating `route.bible` URLs.

### 3. Your app needs hosted parsing, resolution, or QR generation

Use `@route-bible/client` or call the public API.

This is the best option when your app wants:

- hosted parse and ingest
- ranked adapter actions
- translation-aware policy decisions
- QR payload generation
- machine-readable adapter/capabilities metadata

### 4. Your site wants the lightest possible integration

Use `https://route.bible/badge.js`.

This is the best option for article pages, sermon pages, and CMS-driven sites that want a copy-paste integration with minimal app code.

### 5. You want your app to appear inside the route.bible launcher catalog

Stop here and escalate. That is adapter authoring work, not normal app adoption.

## Canonical URL contract

Use this URL shape for published passage links:

`https://route.bible/<canonical-passage>`

Examples:

- `https://route.bible/jhn.3.16`
- `https://route.bible/jhn.3.16-jhn.3.18`
- `https://route.bible/psa.23`

The path should be the lowercase canonical passage slug.

For route URLs, use these query parameters when needed:

- `v`: translation code such as `ESV`, `KJV`, or `BSB`
- `lang`: language hint such as `en`
- `app`: preferred adapter id for human launcher bias
- `src`: source tag for attribution
- `mode`: `auto`, `launcher`, or `web`

Examples:

- `https://route.bible/jhn.3.16?v=ESV`
- `https://route.bible/rom.8.28?src=my_app`
- `https://route.bible/psa.23?mode=web`
- `https://route.bible/jhn.3.16?app=logos&src=sermon_notes`

Mode behavior:

- `mode=auto` (default): if a stored preferred app exists, attempt to open it directly. Otherwise show the launcher.
- `mode=launcher`: always show the launcher, suppressing auto-open even if a preferred app is stored.
- `mode=web`: route to the web reader, but still honor `calendar=1` and explicit `app=<id>` overrides.

Notes:

- Prefer the clean canonical URL with no extra query params unless your app actually needs them.
- Treat `app` as a human preference hint, not as a machine contract.
- For passage-specific machine work, prefer `POST /api/v1/resolve` instead of inferring behavior from the URL alone.

**Important:** `mode=auto` only works when a preferred app is already stored in the browser (set via the "Always open selected app" toggle in the launcher). If no preferred app exists, `mode=auto` falls back to the launcher. The stored preference is keyed by domain, so `mode=auto` on a different domain will not have access to a preference stored on `route.bible`.

## Where to place `route.bible` links in your app

Good places to use `route.bible` links:

- verse cards and highlighted passage chips
- article, commentary, or study pages that mention a passage
- sermon notes, small group guides, and reading plan items
- copy-link, share-link, and export flows
- QR-code generation flows
- fallback buttons such as "Open in Bible app" or "Open in preferred app"
- cross-app handoff points where you cannot assume one provider is installed

Usually avoid replacing these with `route.bible`:

- your app's primary internal reading route
- internal router links that should stay inside your own app
- machine workflows that need ranked actions, policy, or retrieval metadata from the resolver

## Local parsing with `grab-bcv`

Use `grab-bcv` when your app needs local scripture parsing and canonicalization before it builds a `route.bible` URL.

Install:

```bash
pnpm add grab-bcv
```

Recommended local-first flow:

1. Parse or detect a passage with `grab-bcv`.
2. Convert it to a canonical `route.bible` path.
3. Add route query params only when your app needs them.

Example:

```ts
import { parseAnyPassage, parseToResolverPath } from "grab-bcv";

const parsed = parseAnyPassage("John 3:16-18");
const routeUrl = new URL(parseToResolverPath(parsed), "https://route.bible");

routeUrl.searchParams.set("v", "ESV");
routeUrl.searchParams.set("src", "my_app");

console.log(routeUrl.toString());
// https://route.bible/jhn.3.16-jhn.3.18?v=ESV&src=my_app
```

Useful `grab-bcv` functions:

- `parsePassage(input)` for explicit scripture references
- `parseAnyPassage(input)` for human references and shared-link-like input
- `findAnyPassage(input)` when you want `null` instead of throwing
- `formatPassageForDisplay(parsed)` for user-facing text like `John 3:16-18`
- `parseToResolverPath(input)` when you want the canonical `route.bible` path

Use `grab-bcv` when:

- your app already has user text locally
- you want deterministic local parsing without an API round-trip
- you only need a stable canonical path or URL

Do not call `route.bible` just to parse a simple local reference if `grab-bcv` already gives you what you need.

## Hosted integration with `@route-bible/client`

Use `@route-bible/client` when your app needs hosted route.bible services instead of only local parsing.

Install:

```bash
pnpm add @route-bible/client
```

Example:

```ts
import { createRouteBibleClient } from "@route-bible/client";

const client = createRouteBibleClient({ baseUrl: "https://route.bible" });

const parsed = await client.parse({ input: "John 3:16" });

const resolved = await client.resolve({
  input: "John 3:16",
  translation: "ESV",
  app: "logos",
});

const qr = await client.qr({
  input: "John 3:16",
  translation: "ESV",
});
```

Use the hosted client when your app needs:

- `parse()` for typed hosted parsing
- `ingest()` for shared URLs or pasted page payloads
- `resolve()` for ranked actions, policy, and preview metadata
- `qr()` for QR payload generation
- `adapters()` for the current adapter catalog
- `capabilities()` for machine-readable platform and capability metadata
- `openapi()` for the published schema

Important distinction:

- route URLs use `v=` in the query string
- JSON API requests use the `translation` field in the request body

## Public API endpoints

These are the main public endpoints:

- `POST /api/v1/parse`
- `POST /api/v1/ingest`
- `POST /api/v1/resolve`
- `POST /api/v1/qr`
- `GET /api/v1/adapters`
- `GET /api/v1/capabilities`
- `GET /openapi.json`

For passage-specific machine work, treat `POST /api/v1/resolve` as the canonical machine contract.

Do not use `/adapters.txt` for passage-aware decisions.

## Share-target integration

Use `/share-target` when your app or site wants to hand route.bible a page URL and surrounding metadata instead of an already-parsed canonical passage.

Format:

```txt
https://route.bible/share-target?url=<page-url>&title=<title>&text=<summary>&mode=<mode>
```

Use this when:

- your page has article metadata but not a clean canonical passage object
- your CMS can emit a page URL, title, and description more easily than a parsed scripture ref
- you want route.bible to extract a likely passage and redirect into the canonical route flow

The `mode` parameter is forwarded to the canonical route. For example, `mode=auto` will attempt to open the user's stored preferred app directly after share-target parsing, while `mode=launcher` will always show the launcher.

## Badge integration

Use `badge.js` when you want a low-effort website integration.

Quick start:

```html
<div id="route-bible-badge"></div>
<script async src="https://route.bible/badge.js" data-mount="#route-bible-badge"></script>
```

Fixed-passage badge:

```html
<div id="route-bible-badge"></div>
<script
  async
  src="https://route.bible/badge.js"
  data-mount="#route-bible-badge"
  data-passage="jhn.3.16"
  data-src="my_site"
></script>
```

Runtime behavior:

- with `data-passage`, the badge opens that passage in launcher mode
- without `data-passage`, the badge routes through `/share-target` using the current page URL, title, and description

## Recommended implementation patterns

### Pattern A: app already knows the passage

Generate a canonical `route.bible` URL directly.

```ts
const href = "https://route.bible/jhn.3.16";
```

### Pattern B: app has user-entered or imported text

Use `grab-bcv` locally, then build the `route.bible` URL.

### Pattern C: app wants route.bible to decide what to do next

Call `POST /api/v1/resolve` or `client.resolve()`.

### Pattern D: content site wants copy-paste integration

Use `badge.js` or `/share-target`.

## Search-engine redirect integration

You can redirect search results from popular Bible websites to route.bible using a search engine's native redirect rules (where available) or browser-level tools. The recommended approach is to point the redirect at `https://route.bible/share-target?url=<original-url>&mode=auto` so the passage is extracted and the user's preferred app is opened directly.

### Which surface to use?

- **Search engine redirect rules** (Kagi only): Kagi is the only major search engine with native user-configurable redirect rules. No browser extension needed.
- **Browser redirect tools** (Redirector extension, Tampermonkey): Required for Google, Bing, DuckDuckGo, and Brave Search, which do not have user-configurable redirect rules. These work across all engines.
- **Userscript** (Tampermonkey): Best for power users who want a single script across all engines.

### Top 5 search engines

#### Kagi — native redirect rules

Kagi has a built-in "Redirects (URL Rewrites)" feature in Settings → Advanced → Redirects.

Syntax: regex match pattern + pipe (`|`) + replacement pattern. Uses PCRE regex.

**Important:** `$0` does not work in Kagi. Wrap the entire URL in an explicit capture group and use `$1`:

```
^(https://biblehub\.com/.*) | https://route.bible/share-target?url=$1&mode=auto
```

**Example Kagi rules for popular Bible sites:**

```
^(https://(www\.)?bible\.org/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://(www\.)?esv\.org/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://(www\.)?biblia\.com/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://(www\.)?biblestudytools\.com/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://(www\.)?blueletterbible\.org/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://(www\.)?bibleserver\.com/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://www\.biblegateway\.com/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://biblehub\.com/.*) | https://route.bible/share-target?url=$1&mode=auto
^(https://(www\.)?bible\.com/.*) | https://route.bible/share-target?url=$1&mode=auto
```

#### Google — redirect tools or userscript

Google has no built-in redirect rules. Use one of these:

**Option A: Redirector extension** (recommended)
Install [Redirector](https://chrome.google.com/webstore/detail/redirector/ocgpenflpmgnfapjedencafodaog) (Chrome/Firefox/Edge). Add a rule per Bible site:

```
Example URL: https://www.biblegateway.com/passage/?search=John+3%3A16
Include pattern: https://www.biblegateway.com/passage/?search=*
Redirect to: https://route.bible/?q=$1
Pattern type: Wildcard
```

**Option B: Tampermonkey userscript**
Install [Tampermonkey](https://www.tampermonkey.net/) and use the `URL-Modifier-for-Search-Engines` script, which supports Google and 40+ other engines. Add route.bible rules to the script's configuration.

#### DuckDuckGo — redirect tools or userscript

DuckDuckGo has no built-in redirect rules for result rewriting. Options:

**Option A: Submit a DDG bang**
You can submit a `!routebible` bang at [duckduckgo.com/newbang](https://duckduckgo.com/newbang). This lets users type `!routebible John 3:16` in DDG to go directly to route.bible. Note: bangs redirect the query, not the search results.

**Option B: Redirector extension**
Same as Google — works on DuckDuckGo search results.

**Option C: Tampermonkey userscript**
The `URL-Modifier-for-Search-Engines` script explicitly supports DuckDuckGo.

#### Bing — redirect tools or userscript

Bing has no built-in redirect rules. It also wraps result URLs in `bing.com/ck/a` redirect links.

**Option A: Tampermonkey userscript** (recommended)
The `URL-Modifier-for-Search-Engines` script natively handles Bing's redirect-link stripping and strips them before applying your rules.

**Option B: Redirector extension**
Works on Bing search results once the redirect links are stripped.

#### Brave Search — redirect tools or userscript

Brave Search has no built-in redirect rules.

**Option A: Brave Browser Custom Scriptlets**
For Brave Browser users (desktop v1.75+), go to Shields → Content filtering → Developer mode, and add a custom scriptlet that rewrites Bible website URLs on `search.brave.com`.

**Option B: Redirector extension**
Works on Brave Search results.

**Option C: Tampermonkey userscript**
The `URL-Modifier-for-Search-Engines` script explicitly supports Brave Search.

### Userscript redirect approach

For power users who prefer a single script across all browsers and engines:

```javascript
// ==UserScript==
// @name         route.bible Search Redirects
// @match        https://www.google.com/search*
// @match        https://duckduckgo.com/*
// @match        https://www.bing.com/search*
// @match        https://search.brave.com/search*
// @grant        none
// ==/UserScript==

(function() {
    const BIBLE_DOMAINS = [
        'biblegateway.com',
        'biblehub.com',
        'bible.com',
        'blueletterbible.org',
        'biblia.com',
        'biblestudytools.com',
        'bibleserver.com',
        'bible.org',
        'esv.org'
    ];

    function rewriteLinks() {
        for (const a of document.querySelectorAll('a[href]')) {
            const href = a.getAttribute('href');
            if (!href) continue;
            try {
                const url = new URL(href, location.href);
                if (BIBLE_DOMAINS.some(d => url.hostname.includes(d))) {
                    const redirect = new URL('https://route.bible/share-target');
                    redirect.searchParams.set('url', url.toString());
                    redirect.searchParams.set('mode', 'auto');
                    a.href = redirect.toString();
                }
            } catch {
                // skip invalid URLs
            }
        }
    }

    rewriteLinks();
    new MutationObserver(rewriteLinks).observe(document.body, { childList: true, subtree: true });
})();
```

## AI app integration

You can configure AI assistants (ChatGPT, Claude, Perplexity, etc.) to emit route.bible links when they discuss scripture. This makes AI-generated content more portable and actionable for readers.

### Agent Skill approach (recommended)

Install the open `bible-links` Agent Skill anywhere the Agent Skills standard is supported:

```sh
npx skills add dpshde/bible-links --skill bible-links
```

The skill makes route.bible Markdown links the implicit default for unlinked, unambiguous Scripture references. It preserves visible wording and leaves code, existing links, ambiguous fragments, and explicit plain-text requests alone.

Claude Code can also install it directly from the included marketplace:

```text
/plugin marketplace add dpshde/bible-links
/plugin install bible-links@route-bible
```

The same repository includes native manifests for Codex/OpenAI, Cursor, Claude Code, and Claude Cowork. Use the [GitHub source](https://github.com/dpshde/bible-links) or the [Skills.sh listing](https://skills.sh/dpshde/bible-links/bible-links) as the stable installation source.

### Custom instructions approach (no-install fallback)

Most AI assistants support persistent custom instructions. Add a rule like this to your profile or project instructions:

> When you reference Bible passages or scripture, always include a clickable link to route.bible using the canonical format. For example, when discussing John 3:16, write: "For God so loved the world..." ([John 3:16](https://route.bible/jhn.3.16)).

**Where to set it:**
- **ChatGPT:** Settings → Personalization → Custom Instructions
- **Claude:** Settings → Profile → Profile Instructions, or Project Settings → Project Instructions
- **Perplexity:** Settings → Profile → Custom Instructions
- **Grok:** Settings → Custom Instructions
- **t3.chat:** Settings → System Prompt

### Custom userscript approach (power users)

A Tampermonkey userscript can intercept the rendered output of AI chat interfaces and automatically hyperlink scripture references to route.bible. This works even if the AI didn't include the link.

```javascript
// ==UserScript==
// @name         route.bible AI Linkifier
// @match        https://chatgpt.com/*
// @match        https://claude.ai/*
// @match        https://www.perplexity.ai/*
// @match        https://grok.com/*
// @grant        none
// ==/UserScript==

(function() {
    const BIBLE_REF_RE = /\b(?:Genesis|Exodus|Leviticus|Numbers|Deuteronomy|Joshua|Judges|Ruth|1 Samuel|2 Samuel|1 Kings|2 Kings|1 Chronicles|2 Chronicles|Ezra|Nehemiah|Esther|Job|Psalms?|Proverbs|Ecclesiastes|Song of Solomon|Isaiah|Jeremiah|Lamentations|Ezekiel|Daniel|Hosea|Joel|Amos|Obadiah|Jonah|Micah|Nahum|Habakkuk|Zephaniah|Haggai|Zechariah|Malachi|Matthew|Mark|Luke|John|Acts|Romans|1 Corinthians|2 Corinthians|Galatians|Ephesians|Philippians|Colossians|1 Thessalonians|2 Thessalonians|1 Timothy|2 Timothy|Titus|Philemon|Hebrews|James|1 Peter|2 Peter|1 John|2 John|3 John|Jude|Revelation|Gen|Ex|Exo|Lev|Num|Deut|Deu|Josh|Jos|Judg|Jdg|Rut|1 Sam|1Sa|2 Sam|2Sa|1 Kgs|1Ki|2 Kgs|2Ki|1 Chr|1Ch|2 Chr|2Ch|Ezr|Neh|Est|Job|Ps|Psalm|Prov|Pr|Eccl|Ec|Eccles|Song|Sng|So|Sos|Cant|Isa|Is|Jer|Je|Lam|La|Ezek|Eze|Ezk|Dan|Da|Hos|Joel|Jl|Am|Amo|Obad|Oba|Jon|Jnh|Mic|Mc|Mi|Nah|Na|Hab|Hb|Zeph|Zep|Zec|Hag|Hg|Zech|Mal|Ml|Matt|Mt|Mat|Mk|Mrk|Mr|Lk|Luk|Lu|Jn|Jhn|Joh|Acts|Ac|Rom|Ro|Rm|1 Cor|1Co|2 Cor|2Co|Gal|Ga|Eph|Ephes|Php|Phil|Php|Col|1 Thess|1Th|2 Thess|2Th|1 Tim|1Ti|2 Tim|2Ti|Tit|Philem|Phm|Heb|He|Jas|Jm|1 Pet|1Pe|2 Pet|2Pe|1 Jn|1Jo|2 Jn|2Jo|3 Jn|3Jo|Jude|Jud|Ju|Rev|Re|Rv|Apoc)\s+\d+(?::\d+(?:\s*[\-\u2013\u2014]\s*\d+)?)?\b/g;

    function linkify(node) {
        if (node.nodeType !== Node.TEXT_NODE) return;
        const text = node.textContent;
        if (!text || !BIBLE_REF_RE.test(text)) return;
        BIBLE_REF_RE.lastIndex = 0;

        const parent = node.parentNode;
        if (parent.closest('a, code, pre')) return;

        const parts = [];
        let lastIndex = 0;
        let match;
        while ((match = BIBLE_REF_RE.exec(text)) !== null) {
            if (match.index > lastIndex) {
                parts.push(document.createTextNode(text.slice(lastIndex, match.index)));
            }
            const ref = match[0];
            const a = document.createElement('a');
            a.href = `https://route.bible/?q=${encodeURIComponent(ref)}&mode=auto`;
            a.textContent = ref;
            a.target = '_blank';
            a.rel = 'noopener noreferrer';
            parts.push(a);
            lastIndex = match.index + ref.length;
        }
        if (lastIndex < text.length) {
            parts.push(document.createTextNode(text.slice(lastIndex)));
        }
        if (parts.length > 1) {
            parent.replaceChildren(...parts);
        }
    }

    function scan() {
        const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
        const nodes = [];
        while (walker.nextNode()) nodes.push(walker.currentNode);
        for (const node of nodes) linkify(node);
    }

    scan();
    new MutationObserver(scan).observe(document.body, { childList: true, subtree: true });
})();
```

### API-driven approach (for developers)

If you are building an AI-powered app or chatbot, call `POST /api/v1/resolve` to get canonical route.bible URLs and ranked actions for any passage the AI references:

```ts
import { createRouteBibleClient } from "@route-bible/client";

const client = createRouteBibleClient({ baseUrl: "https://route.bible" });

// In your AI response post-processing:
const resolved = await client.resolve({
  input: "John 3:16",
  app: "logos",       // hint for the user's preferred destination
  translation: "ESV", // hint for translation
});

// Embed the canonical URL in your AI output:
const routeUrl = resolved.routeUrl;
```

## What not to do

- Do not treat `?app=<id>` as the canonical machine interface.
- Do not use `/adapters.txt` for resolver logic.
- Do not replace your own internal reader route unless portability is the actual goal.
- Do not hard-code one third-party Bible provider when your product goal is app-agnostic handoff.
- Do not create provider-specific scripture URLs if a canonical `route.bible` URL would serve the same user outcome.

## QA checklist

After implementing `route.bible` support, verify:

- generated links use lowercase canonical passage slugs
- translation, source tag, and mode propagate correctly when you include them
- a copied or shared `route.bible` URL works on desktop and mobile
- your app still keeps internal reading/navigation where that is the intended primary flow
- badge or share-target flows extract the expected passage from representative pages
- if you use `resolve()`, the app handles ranked actions and fallback metadata without assuming one provider always wins

## Escalate when this becomes adapter work

Normal app adoption stops here.

If your goal is to make your app itself show up as a first-class destination inside the route.bible launcher, that is adapter-authoring work and should be handled separately.
