Michael J Wright Archive Documentation

Syndication Consumer Setup — MJW-com-au

This guide is for the consumer project (your Vite/React app hosted on Cloudflare) that will render galleries and pages by fetching curated items from this archive.

What secrets/tokens does MJW-com-au need?

Required (for syndication endpoints)

Recommended config (non-secret)

Why you should not put the API key in the browser

The archive API key should be treated as a credential. If you put it in a Vite VITE_* variable, it ends up in client-side JS and can be copied.

Recommended approach:

Provider-side requirements (configured in THIS repo)

Before MJW-com-au can access the syndication API, the archive provider must configure:

If CORS_ALLOW_ORIGINS is empty, browser calls will be blocked by the strict CORS policy for /api/v1/*.

Endpoints MJW-com-au will call

All are read-only:

Swagger UI (provider):

Minimal Cloudflare Pages Function proxy (recommended)

Create a Pages Function in MJW-com-au:

It proxies requests from the browser to the archive API and injects the API key.

export async function onRequest(context) {
  const { request, env, params } = context;

  const upstreamBase = env.MJW_ARCHIVE_BASE_URL || 'https://api.michaeljwright.com.au';
  const apiKey = env.MJW_SYNDICATION_API_KEY;
  if (!apiKey) {
    return new Response('Server not configured', { status: 500 });
  }

  const path = (params.path || []).join('/');
  const url = new URL(request.url);
  const upstreamUrl = `${upstreamBase}/${path}${url.search}`;

  const headers = new Headers(request.headers);
  headers.set('X-Api-Key', apiKey);

  // Keep your own site strict too:
  headers.delete('cookie');
  headers.delete('authorization');

  const upstreamReq = new Request(upstreamUrl, {
    method: 'GET',
    headers,
  });

  return fetch(upstreamReq);
}

Then your React app calls:

Secrets to set in MJW-com-au (Cloudflare)

In the Cloudflare dashboard for the MJW-com-au project:

That’s it.