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)
MJW_SYNDICATION_API_KEY(secret)- Value: the collaboration-only API key issued by the archive maintainers.
- Used as:
X-Api-Key: <key>when calling the archive.
Recommended config (non-secret)
MJW_ARCHIVE_BASE_URL(public config)- Value:
https://api.michaeljwright.com.au
- Value:
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:
- Add a server-side proxy inside MJW-com-au (Cloudflare Pages Functions or a Cloudflare Worker)
- The browser calls your proxy
- The proxy attaches
X-Api-Keyand forwards to the archive
Provider-side requirements (configured in THIS repo)
Before MJW-com-au can access the syndication API, the archive provider must configure:
SYNDICATION_API_KEYS(Worker secret in api.data Worker): includes the partner key value.FEDORA_BASIC_AUTH(Worker secret in api.data Worker): required so the provider Worker can read from Fedora.- If this is missing,
/api/v1/*item listing endpoints will return500with:Server not configured: missing FEDORA_BASIC_AUTH. - Recommended: derive it from the least-privilege Fedora service account in
config/runtime.env.
- If this is missing,
CORS_ALLOW_ORIGINS(Worker var in api.data Worker): must include MJW-com-au production origin(s), for example:https://mjw-com-au.pages.devhttps://michaeljwright.com.au
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:
GET /api/v1/collectionsGET /api/v1/collections/{collection}/items?limit=&offset=&series=&ids=GET /api/v1/items/{catalogId}
Swagger UI (provider):
https://api.michaeljwright.com.au/syndication/swagger
Minimal Cloudflare Pages Function proxy (recommended)
Create a Pages Function in MJW-com-au:
- File:
functions/api/mjw/[...path].js
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:
/api/mjw/api/v1/collections/api/mjw/api/v1/collections/paintings/items?limit=24&offset=0
Secrets to set in MJW-com-au (Cloudflare)
In the Cloudflare dashboard for the MJW-com-au project:
- Secret:
MJW_SYNDICATION_API_KEY=<issued key> - Variable:
MJW_ARCHIVE_BASE_URL=https://api.michaeljwright.com.au
That’s it.