Flutter can build web apps that behave like native mobile apps, and you can deploy those Progressive Web Apps (PWAs) for free on GitHub Pages. You only need a few commands to get there. You can also buy a custom domain and hook it up so your app looks more professional. Here’s how to do it.
1. Create a Flutter Web Project
Make a new Flutter project or convert an existing one. If you don’t have Flutter installed, install it from the official Flutter docs.
flutter create my_pwa
cd my_pwa
2. Enable Web Support
Flutter supports web out of the box now, but just double-check.
flutter config --enable-web
flutter doctor
You should see Chrome, Edge, or other browsers listed under available devices.
3. Add PWA Assets
Flutter generates basic PWA support automatically when you run a web build. But if you want to customize icons or the manifest, look inside web/
and edit the manifest.json
, favicon.png
, etc.
4. Build for the Web
Run a release build for web:
flutter build web --release
Flutter places the result in build/web
. You can rename it if you want, but build/web
works fine.
You can test your app by running this and then picking your browser.
flutter run
5. Push to GitHub
Go to GitHub and create a new repo. Then, in your local project directory:
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/your-username/my_pwa.git
git push -u origin master
6. Deploy on GitHub Pages
GitHub Pages can serve any static files from a branch or a folder. A simple way:
- In your repo, go to Settings > Pages.
- Under Source, choose the branch (
master
ormain
) and set the folder to/docs
orroot
. - Move your
build/web
folder contents into a folder nameddocs
(or whatever folder you picked).
cd build/web
cp -r * ../../docs
- Commit and push again:
cd ../../docs
git add .
git commit -m "Deploy PWA to GitHub Pages"
git push
Your app should appear at https://<your-username>.github.io/<repo-name>
.
7. Hook Up a Custom Domain
You can purchase a domain from a registrar like Godaddy or Namecheap. In your repo’s Settings > Pages, you’ll see a section for Custom domain. Add your domain (like mycoolapp.com
). Then create a CNAME
file in your repo’s root (or docs folder) with the domain name inside.
Example CNAME
file:
mycoolapp.com
Follow the instructions from this GitHub documentation to configure the DNS settings in the registrar's DNS settings.
8. Verify Your PWA
Open your URL in Chrome and look in DevTools > Application. Check the Manifest and Service Worker sections. If everything looks right, your app can be installed like a native app.
You can install the app on your desktop as an icon by tapping the install button in the URL bar.
9. Check the Config
If you have any issues with deploying your app, you can see an existing example. The Flutter Material Design Seed Color picker is an app that helps you select a Material Design 3 seed color for your app. This is the example index.html
See the original here.
<!DOCTYPE html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A tool for time boxing with AI">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="temporalo">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png" />
<title>temporalo</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>
- Deploy WebAssembly Version
You can go a step further build and deploy your app as a Wasm app. This improves the performance of the Flutter app
Here is an example Github Actions script. You can get the original here.
name: Deploy to GitHub Pages
on:
push:
branches: [ "main" ]
workflow_dispatch:
permissions:
contents: write
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.ref }}
fetch-depth: 0
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.29.0'
channel: 'stable'
architecture: x64
- name: Enable WASM
run: flutter config --enable-web
- name: Get dependencies
run: flutter pub get
- name: Build WASM
run: flutter build web --wasm --release --base-href "/${{ github.event.repository.name }}/"
- name: Update COOP and COEP headers
run: |
echo '{
"headers": [
{
"source": "**/*",
"headers": [
{
"key": "Cross-Origin-Embedder-Policy",
"value": "credentialless"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
}
]
}
]
}' > build/web/_headers
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'build/web'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
- name: Get Version
id: version
run: |
VERSION=$(grep 'version:' pubspec.yaml | sed 's/version: //')
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Configure git
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
# Create tag
TAG_NAME="v${VERSION}"
git tag "$TAG_NAME"
git push origin "$TAG_NAME"
# Create release
gh release create "$TAG_NAME" \
--title "v${VERSION} Web Release" \
--notes "Web deployment v${VERSION}" \
--target ${{ github.sha }}
See the live running sample app here. And, if you get stuck, you can see all the code and config for this app and here.
You now have a fully functional Flutter PWA on GitHub Pages. Anyone can hit this URL, and you don't have to pay anything. Pick up a custom domain if you want a professional URL. Then keep iterating, pushing commits, and adding features. Your PWA will update instantly, no extra steps needed.
If you're looking for a quality company to build your web app, please get in contact with Nimblesite.
Top comments (0)