YouVersion PlatformYouVersion Platform
PlatformBiblesDev Docs
CommunityPartnersSupport

YouVersion Platform

Build applications and integrate with the world's most popular Bible platform.

Platform Products

  • Platform Portal
  • Developer Documentation
  • App Management

Resources

  • Support
  • Press inquiries

Legal

  • Privacy Policy
  • Terms of Use

© 2026 YouVersion. All rights reserved.

  • Overview
  • API Reference
  • SDKs
  • Changelog
<  Back to Platform
Getting Started
    YouVersion Platform OverviewAPI Usage
Guides
    Display Bible HTMLSign-in APIsSearch APIsUSFM ReferenceError Codes
Useful Links
    YouVersionGitHub
Guides

Display Bible HTML

Use this guide when you want to display Bible text on the web without a YouVersion React component. The recommended JavaScript API returns everything the page needs together:

  • transformed, sanitized Bible HTML
  • current Bible version attribution
  • the Bible CSS and font stylesheet URLs
  • the attributes that scope YouVersion styles to your container

If you use React and want a ready-made component, use BibleTextView instead.

Recommended: use the JavaScript SDK

Install the framework-independent core package:

TerminalCode
npm install @youversion/platform-core

Create a client and request a display-ready passage. A passage ID uses USFM format, such as JHN.3.16 for John 3:16.

Code
import { ApiClient, BibleClient } from "@youversion/platform-core"; const bibleClient = new BibleClient( new ApiClient({ appKey: "YOUR_APP_KEY" }), ); const display = await bibleClient.getPassageDisplay({ versionId: 3034, // Berean Standard Bible passageId: "JHN.3.16", includeHeadings: true, includeNotes: true, });

getPassageDisplay always returns transformed HTML. It also fetches the Bible version metadata on every call so its required attribution is current. If the version has no usable attribution, the call fails instead of returning an incomplete display model.

The result is declarative: the SDK returns data but does not modify the DOM, inject resources, or cache attribution.

Render in a browser

Start with an empty container:

Code
<article id="bible-text"></article> <p id="bible-attribution"></p>

Then install the returned stylesheets and content:

Code
const root = document.querySelector<HTMLElement>("#bible-text"); const attribution = document.querySelector<HTMLElement>("#bible-attribution"); if (!root || !attribution) throw new Error("Missing Bible display elements"); for (const stylesheet of display.stylesheets) { if (document.querySelector(`[data-yv-stylesheet="${stylesheet.kind}"]`)) { continue; } const link = document.createElement("link"); link.rel = stylesheet.rel; link.href = stylesheet.href; link.dataset.yvStylesheet = stylesheet.kind; document.head.append(link); } for (const [name, value] of Object.entries(display.containerAttributes)) { root.setAttribute(name, value); } root.innerHTML = display.html; attribution.textContent = display.attribution.text;

The SDK sanitizes and transforms display.html, so it is intended for the browser's HTML rendering API. Keep attribution as text, as shown above.

For a client-side framework other than React, apply the returned container attributes to the component that owns the Bible HTML, add each stylesheet to the document head, and use the framework's raw-HTML escape hatch only for display.html. Render display.attribution.text normally.

Render on a server

Server-side transformation uses jsdom, an optional peer dependency:

TerminalCode
npm install @youversion/platform-core jsdom

Call getPassageDisplay on the server exactly as in the recommended example. Add the returned resources to the document head and emit the Bible HTML inside the scoped container:

Code
function escapeHtml(value: string) { return value .replaceAll("&", "&amp;") .replaceAll("<", "&lt;") .replaceAll(">", "&gt;") .replaceAll('"', "&quot;"); } const stylesheetLinks = display.stylesheets .map( ({ href }) => `<link rel="stylesheet" href="${escapeHtml(href)}">`, ) .join("\n"); const page = ` ${stylesheetLinks} <article data-yv-sdk data-slot="yv-bible-renderer"> ${display.html} </article> <p>${escapeHtml(display.attribution.text)}</p> `;

display.html is the only value intentionally emitted without escaping. Continue to escape attributes and attribution, or let your template engine escape them.

Without npm: use the REST API

If you cannot install the JavaScript SDK, fetch the passage and Bible version directly. The API's Bible HTML is safe to render, but it is not transformed like SDK HTML. Bible CSS still provides a readable basic presentation; verse-level targeting, normalized tables, and extracted footnote data require the SDK transformation.

Add the two required stylesheets to the page:

Code
<link rel="stylesheet" href="https://cdn.youversion.com/platform/1/bible.css"> <link rel="stylesheet" href="https://api.youversion.com/v1/fonts/1/stylesheet?app_key=YOUR_APP_KEY">

Then fetch both resources and display them:

Code
const appKey = "YOUR_APP_KEY"; const versionId = 3034; const passageId = "JHN.3.16"; const headers = { "X-YVP-App-Key": appKey }; const passageUrl = `https://api.youversion.com/v1/bibles/${versionId}/passages/${encodeURIComponent(passageId)}?format=html`; const [passageResponse, versionResponse] = await Promise.all([ fetch(passageUrl, { headers }), fetch(`https://api.youversion.com/v1/bibles/${versionId}`, { headers }), ]); if (!passageResponse.ok || !versionResponse.ok) { throw new Error("Unable to load Bible text"); } const passage = await passageResponse.json(); const version = await versionResponse.json(); const attributionText = version.copyright?.trim() || version.promotional_content?.trim(); if (!attributionText) { throw new Error("This Bible version has no display attribution"); } const root = document.querySelector("#bible-text"); const attribution = document.querySelector("#bible-attribution"); if (!root || !attribution) throw new Error("Missing Bible display elements"); root.setAttribute("data-yv-sdk", ""); root.setAttribute("data-slot", "yv-bible-renderer"); root.innerHTML = passage.content; attribution.textContent = attributionText;

See the Bibles API and Fonts API for endpoint details.

Font delivery

Untitled Serif is the intended Bible typeface, and font ID 1 is its permanent Platform identifier. Load it through the Fonts API stylesheet returned by getPassageDisplay, or through the URL shown above. Do not download or self-host its font files. The Bible CSS includes a fallback font if Untitled Serif cannot load.

If an app key contains reserved URL characters, URL-encode it before placing it in the manual font stylesheet URL. The SDK does this automatically.

Customize the reader

Set the supported reader tokens on the scoped container:

Code
[data-slot="yv-bible-renderer"] { --yv-reader-font-family: "Untitled Serif", "Source Serif 4", serif; --yv-reader-font-size: 20px; --yv-reader-line-height: 1.625; --yv-reader-max-width: 65ch; }

For dark tokens, add data-yv-theme="dark" to the container or an ancestor that also has data-yv-sdk.

Transformed HTML makes verse-level styling predictable. For example:

Code
[data-slot="yv-bible-renderer"] .yv-v[v="16"] { background: color-mix(in srgb, currentColor 10%, transparent); } [data-slot="yv-bible-renderer"] [data-verse-footnote] { cursor: pointer; }

Prefer the reader tokens for typography and layout. Treat other Bible CSS classes and generated markup as content structure rather than a general theming API.

Content security policy

For a strict Content Security Policy, allow:

  • https://cdn.youversion.com in style-src and font-src
  • https://api.youversion.com in style-src

Related documentation

  • Copyright & Attribution
  • JavaScript SDK
  • Passage IDs and USFM
  • API authentication
Last modified on September 14, 2026
API UsageSign-in APIs
On this page
  • Recommended: use the JavaScript SDK
  • Render in a browser
  • Render on a server
  • Without npm: use the REST API
  • Font delivery
  • Customize the reader
  • Content security policy
  • Related documentation
TypeScript
TypeScript
TypeScript
Javascript
CSS
CSS