Serving JSON Data from GitHub Pages

Short answer

How do you serve JSON data from GitHub Pages?

Commit a .json file to the branch or folder GitHub Pages publishes, for example data/items.json, and fetch it at https://user.github.io/repo/data/items.json. Pages serves it as static content with CORS open to all origins, so browsers can read it directly. Regenerate the file from a scheduled GitHub Action to keep the data fresh.

Step by step

  1. 1

    Add the file

    Place the JSON file in the publishing source of your Pages site and commit it.

  2. 2

    Fetch it by URL

    Request it from your Pages domain with fetch() or any HTTP client. It behaves like a read-only API.

  3. 3

    Mind the cache

    Pages caches files for about ten minutes, so updates are not instant. Add a version query string when you need a fresh copy.

  4. 4

    Automate updates

    Use a scheduled GitHub Action to collect data, write the JSON file and commit it.

Example

JavaScript
const res = await fetch(
  "https://your-user.github.io/your-repo/data/items.json",
);
const items = await res.json();
console.log(items.length);

Frequently Asked Questions

Can GitHub Pages accept writes?

No. It only serves static files. Updates happen by committing a new version of the file, usually from a GitHub Action.

Is there a size limit?

Published sites should stay under 1 GB and individual files well below GitHub's 100 MB file limit. Split large datasets into several files.

Try it with AlterLab

Send a URL, get the page back as HTML, markdown or JSON. Rendering, proxy rotation and retries are handled for you.

View API docs

Your first scrape.
Sixty seconds.

Up to 5,000 free requests — about 5,000 Light, 500 Protected or 250 Dynamic requests. No credit card.Just a POST request.

terminal
curl -X POST https://api.alterlab.io/v1/scrape \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "formats": ["markdown"]}'

No credit card required · Up to 5,000 free requests (about 5,000 Light, 500 Protected or 250 Dynamic requests) · Balance never expires