Skip to content

How to host a profile

A researcher profile is a directory of static files. Hosting one means serving that directory over HTTP from S3, GitHub Pages, nginx, or Cloudflare. There is no application to run and no database to provision.

Copy the profile directory to your host. The entry point is profile.jsonld; every other file is reachable from its manifest.

Privacy filtering happens at deploy time via .publishignore, a newline-delimited list of artifacts above public tier (see Privacy tiers):

Terminal window
rsync -a --exclude-from=profiles/doe-jane/.publishignore \
profiles/doe-jane/ <dest>/

This drops restricted artifacts (.cache/, sources/papers/ full text, sources/cv.md, sources/web/) automatically.

A conformant host must:

  1. Serve Access-Control-Allow-Origin: * on all responses (including OPTIONS)
  2. Serve .jsonld files as application/ld+json
  3. Return a real 404 for missing paths (not a 200 HTML shell)
  4. Support Range requests for embedding blobs (.bin)
Section titled “Cloudflare Workers Static Assets (recommended)”

A Worker overlay in front of the ASSETS binding sets headers on every response. Two settings in wrangler.toml matter:

  • run_worker_first = true: without it the Worker only runs on asset misses
  • not_found_handling must be "404-page", not "single-page-application"

GitHub Pages cannot set custom headers (so no CORS) and serves .jsonld as application/octet-stream. Use it only behind a proxy (Cloudflare, or a Worker that fetches and overrides headers).

Set Content-Type per object at upload; add CORS via CloudFront response headers policy:

Terminal window
aws s3 cp profile.jsonld s3://bucket/p/slug/profile.jsonld \
--content-type "application/ld+json; charset=utf-8"
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
add_header Access-Control-Expose-Headers "Content-Length, Content-Range";
}
location ~* \.jsonld$ {
types { }
default_type application/ld+json;
add_header Access-Control-Allow-Origin *;
}
profiles.example.org {
header Access-Control-Allow-Origin *
header Access-Control-Allow-Methods "GET, HEAD, OPTIONS"
root * /var/www/profiles
file_server
@jsonld path *.jsonld
header @jsonld Content-Type "application/ld+json; charset=utf-8"
}

Once deployed, set url in profile.jsonld to the published location. For ORCID-verified profiles, this URL must appear in the ORCID record’s website list.

Set license to a licence IRI. A profile with no declared reuse terms leaves consumers guessing.

The explorer app (rp-browser/) includes a conformance validator. Paste your profile URL and it checks the schema, CORS headers, and content types. This catches silent failures that make a profile unreachable to browser-based consumers.

See also: How to validate a profile