Deploying
Observable Framework documentation: Deploying Source: https://observablehq.com/framework/deploying
You can host your built Framework app on any static site hosting service, or self-host it with any static site server. This guide covers automating deploys to GitHub Pages with GitHub Actions, and assumes that you are hosting your Framework project’s git repository on GitHub.
<div class="tip">If you don’t yet have an app ready to deploy, create one by following our Getting started guide.
</div>In your git repository, create the file .github/workflows/deploy.yml with the following contents:
name: Deploy
on:
# Run this workflow whenever a new commit is pushed to main.
push: {branches: [main]}
# Run this workflow once per day, at 10:15 UTC
schedule: [{cron: "15 10 * * *"}]
# Run this workflow when triggered manually in GitHub’s UI.
workflow_dispatch: {}
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build
- uses: actions/configure-pages@v4
- uses: actions/upload-pages-artifact@v3
with:
path: dist
- name: Deploy
id: deployment
uses: actions/deploy-pages@v4
Commit this file to your main branch and push to GitHub. Then follow GitHub’s instructions to specify GitHub Actions as the source for GitHub Pages.
After you’ve performed these steps, the deploy.yml above will automatically build and deploy your app once per day (to keep your data up-to-date), as well as whenever you push new commits to your GitHub repository’s main branch (so you can make changes at any time). You will also be able to manually trigger a deploy through GitHub’s user interface. If you like, you can disable any of these triggers (push, schedule, or workflow_dispatch) by updating the deploy.yml file.
Caching
If some of your data loaders take a long time to run, or simply don’t need to be updated every time you build, you can set up caching to automatically re-use existing data from previous builds. To do that, add the following steps to your deploy.yml before npm run build:
jobs:
deploy:
steps:
# …
- id: date
run: echo "date=$(TZ=America/Los_Angeles date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- id: cache-data
uses: actions/cache@v4
with:
path: src/.observablehq/cache
key: data-${{ hashFiles('src/data/*') }}-${{ steps.date.outputs.date }}
# …
<div class="note">
This will only cache data loaders that live under <code>src/data</code>. You’ll need to edit the paths above if you’ve configured a source root other than <code>src</code>, or if the data loaders you want to cache live elsewhere.
</div>This uses one cache per calendar day (in the America/Los_Angeles time zone). If you deploy multiple times in a day, the results of your data loaders will be reused on the second and subsequent runs. You can customize the date and cache-data steps to change the cadence of the caching. For example you could use date +'%Y-%U' to cache data for a week or date +'%Y-%m-%dT%H' to cache it for only an hour.