Frameworks

Plain JavaScript

Display approved content on an ordinary HTML page without a framework or API key.

PeopleTide Content · HTTP integration guides

1. Prepare your project.

Save delivery.js beside index.html. Replace the UUID placeholders below. Serve both files over HTTP locally or HTTPS in production; ES modules do not run reliably from file URLs.

2. Add the shared delivery helper.

Copy this helper into the path named above. It follows a single published release without exposing authoring credentials.

JavaScript
// delivery.js — no SDK or API key required. Node 22+ or a modern browser.
export async function getArticle({ origin, organization, site, slug }) {
  const base = new URL(origin);
  if (base.protocol !== 'https:' && !['localhost', '127.0.0.1'].includes(base.hostname)) {
    throw new Error('Use an HTTPS Content origin');
  }
  if (![organization, site].every(id => /^[a-f0-9-]{36}$/.test(id))) {
    throw new Error('Set your organization and site UUIDs');
  }
  const prefix = '/delivery/v1/' + organization + '/' + site + '/';
  async function read(path) {
    const url = new URL(path, base);
    if (url.origin !== base.origin || !url.pathname.startsWith(prefix) || url.search || url.hash) {
      throw new Error('Unexpected delivery URL');
    }
    const response = await fetch(url, {
      credentials: 'omit', cache: 'no-store', redirect: 'error',
      signal: AbortSignal.timeout(8000),
    });
    if (!response.ok) throw new Error('Content delivery returned ' + response.status);
    return response.json();
  }
  const current = await read(prefix + 'current.json');
  const manifest = await read(current.url);
  const entry = manifest.entries.find(item => item.type === 'article' && item.slug === slug);
  if (!entry) return null;
  const document = await read(entry.url);
  return { releaseId: current.releaseId, document };
}

Connect and render.

Publish an article of type article with slug welcome and a body field before running the example. Split the labelled files into the paths shown.

HTML
<!-- index.html -->
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Journal</title></head>
<body><main><h1 id="title">Journal</h1><p id="body" style="white-space: pre-wrap"></p>
<p id="status" role="status">Loading article…</p></main>
<script type="module" src="/article.js"></script></body></html>

// article.js
import { getArticle } from './delivery.js';
const status = document.querySelector('#status');
try {
  const result = await getArticle({ origin: 'https://content.peopletide.com',
    organization: 'YOUR_ORGANIZATION_UUID', site: 'YOUR_SITE_UUID', slug: 'welcome' });
  if (!result) status.textContent = 'Article not published.';
  else {
    document.querySelector('#title').textContent = result.document.title;
    document.querySelector('#body').textContent = result.document.fields.body || '';
    status.textContent = '';
  }
} catch { status.textContent = 'Content temporarily unavailable.'; }

Choose when content refreshes.

The page fetches when loaded. It does not poll or change the browser’s HTTP document status. Keep using textContent for plain text. Add the Content origin to connect-src in your own site’s CSP and permitted media origins to img-src.

Verify success and failure.

Serve with a local static server, open the page, and inspect requests to current.json, its manifest, and the article. Confirm no credential header and useful missing-content and offline messages.