Leveraging GitHub Pages for free static site hosting combined with the powerful automation of GitHub Actions offers a robust CI/CD pipeline for front-end applications. This guide will walk you through deploying Vue 3, SvelteKit, and Angular 20 applications, highlighting how GitHub Actions can manage sensitive environment variables that simpler deployment methods like Angular’s ng deploy
cannot.
Common Deployment Principles with GitHub Actions
Regardless of your chosen framework, the core principles for deploying to GitHub Pages via GitHub Actions remain consistent:
- GitHub Actions Workflow: A
.github/workflows/main.yml
file defines the steps for building and deploying your application. - Environment Variables & Secrets: For sensitive data like API keys, GitHub Secrets are crucial. These are securely injected during the build process in GitHub Actions, preventing them from being committed to your public repository.
- Static Site Enhancements:
.nojekyll
file: An empty.nojekyll
file placed in the root of your deployed site prevents GitHub Pages from processing it with Jekyll, ensuring your single-page application (SPA) behaves as expected.404.html
file: Copying yourindex.html
to404.html
provides a fallback for non-existent routes, essential for SPAs on GitHub Pages.
Vue 3 Application Deployment
Vite Configuration
For a Vue 3 application built with Vite, you need to set the base
property in vite.config.ts
to specify the base URL for your deployed application. This ensures correct asset paths on GitHub Pages.
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
base: '/vue-github-profile/', // <-- Set your repository name here
plugins: [
vue(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
After this, run npm run build
to compile your application into the dist/
directory.
GitHub Actions Workflow for Vue 3
The following main.yml
sets up the build and deployment process. It includes steps to install Node.js, install dependencies, build the application (passing VITE_GITHUB_TOKEN
as an environment variable), create .nojekyll
and 404.html
, and finally deploy to GitHub Pages.
name: Deploy Vue to GitHub Pages
on:
push:
branches:
- main
workflow_dispatch:
permissions:
id-token: write
contents: read
pages: write
jobs:
build-and-deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Build site
env:
VITE_GITHUB_TOKEN: ${{ secrets.VITE_GITHUB_TOKEN }} # Your sensitive environment variable
run: npm run build
- name: Add .nojekyll file
run: touch dist/.nojekyll
- name: Add 404.html file
run: cp dist/index.html dist/404.html
- name: Configure GitHub Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./dist
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
SvelteKit Application Deployment
Adapter Configuration
SvelteKit requires the @sveltejs/adapter-static
package to output a static site compatible with GitHub Pages. Install it with:
npm i --sav-exact --save-dev @sveltejs/adapter-static
Then, modify your svelte.config.ts
to use this adapter, setting the fallback
for 404 pages and defining the base
path for your repository.
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter({
fallback: '404.html' // SvelteKit automatically creates this
}),
paths: {
base: '/svelte-github-profile' // <-- Set your repository name here
}
}
};
export default config;
GitHub Actions Workflow for SvelteKit
The SvelteKit workflow is very similar to Vue, but it outputs to the build/
directory and automatically handles the 404.html
creation.
name: Deploy SvelteKit to GitHub Pages
on:
push:
branches:
- main
workflow_dispatch:
permissions:
id-token: write
contents: read
pages: write
jobs:
build-and-deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Build site
env:
VITE_GITHUB_TOKEN: ${{ secrets.VITE_GITHUB_TOKEN }} # Example sensitive variable if needed
run: npm run build
- name: Add .nojekyll file
run: touch build/.nojekyll # Note: SvelteKit outputs to 'build/'
- name: Configure GitHub Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./build # Upload from the 'build/' directory
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Angular 20 Application Deployment
Why GitHub Actions over ng deploy
?
While ng deploy
offers convenience, it typically relies on configuration files that might be committed to your repository. If your Angular application uses sensitive environment variables (e.g., API keys), committing these via angular.json
is a security risk for public repositories. GitHub Actions allows you to inject these secrets securely during the build phase.
Angular Configuration (`angular.json`)
Adjust your angular.json
to ensure the build output path is straightforward for GitHub Actions. Under architect -> build -> options
, set the outputPath
:
"outputPath": {
"base": "dist",
"browser": ""
}
Ensure your package.json
‘s build script calls ng build
:
"scripts": {
"ng": "ng",
"build": "ng build",
}
GitHub Actions Workflow for Angular 20
The Angular workflow explicitly passes environment variables and the base href during the npm run build
command.
name: Deploy Angular to GitHub Pages
on:
push:
branches:
- main
workflow_dispatch:
permissions:
id-token: write
contents: read
pages: write
jobs:
build-and-deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Install dependencies
run: npm install
- name: Build site
run: npm run build -- --define SECRET_GITHUB_TOKEN='${{ secrets.SECRET_GITHUB_TOKEN }}' --base-href=https://railsstudent.github.io/angular-github-profile/ # Pass secrets and base-href
- name: Add .nojekyll file
run: touch dist/.nojekyll
- name: Add 404.html file
run: cp dist/index.html dist/404.html
- name: Configure GitHub Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./dist
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
Configuring GitHub Repository Settings
After setting up your YAML file, you need to configure your GitHub repository:
- Create an Environment: Navigate to
https://github.com/<your-username>/<repo-name>/settings/environments
. Verify that agithub-pages
environment is created by the first workflow run. You can configure deployment branches here (e.g., allow onlymain
). - Add Environment Secrets: In the
github-pages
environment settings, click “Add environment secret” to add any necessary secrets (e.g.,VITE_GITHUB_TOKEN
orSECRET_GITHUB_TOKEN
). - Set GitHub Pages Source: Go to
https://github.com/<your-username>/<repo-name>/settings/pages
and select “GitHub Actions” as the source for “Build and deployment”.
Each commit to your specified branch (e.g., main
) will now trigger a new deployment automatically. Verify the live site after deployment.
Resources
- Vue 3 Deployment: https://dev.to/ishmam_abir/publish-a-vuejs-3vite-project-on-github-pages-2a0b
- SvelteKit Deployment: https://svelte.dev/docs/kit/adapter-static#GitHub-Pages
- Angular Build: https://angular.dev/cli/build
GitHub Repositories (Demos)
- Vue 3: https://github.com/railsstudent/vue-github-profile
- Svelte 5: https://github.com/railsstudent/svelte-github-profile
- Angular 20: https://github.com/railsstudent/angular-github-profile