4.9 KiB
Publishing zelo-news as an Android App (TWA / Capacitor)
This document collects the concrete steps, templates and commands you can use to publish the zelo-news progressive web app to an Android store. It assumes you've already built the web app into dist/ (run npm ci && npm run build).
TL;DR — recommended route for Play Store:
- Host
dist/on HTTPS (e.g. Vercel or Netlify) - Use Bubblewrap to generate a Trusted Web Activity (TWA) Android project
- Host a
/.well-known/assetlinks.jsonwith your app package and SHA-256 fingerprint - Build an AAB and upload to Google Play Console
Prerequisites
- Node.js + npm
- Java JDK 11+
- Android SDK & Android Studio (for building / signing the AAB)
- A public HTTPS origin for your site (e.g. https://example.com)
- Build the web app
cd /path/to/zelo-news
npm ci
npm run build
# verify dist/
ls -la dist
- Deploy
dist/to HTTPS hosting
- Deploy the
dist/folder to Netlify, Vercel, or another HTTPS host. - Ensure the manifest is reachable at
https://YOUR_ORIGIN/manifest.webmanifestand the site works over HTTPS.
Quick Netlify deploy (optional):
# install netlify CLI (optional)
npm i -g netlify-cli
netlify deploy --dir=dist --prod
- Asset Links (required for TWA)
- You must host a
/.well-known/assetlinks.jsonfile at the root of your origin. - The file ties your Android app package name and signing key to the web origin.
- Use the
docs/assetlinks-template.jsonfile in this repo as a starting point.
Template (replace placeholders):
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example.yourapp",
"sha256_cert_fingerprints": [
"YOUR_SHA256_FINGERPRINT"
]
}
}
]
How to get the SHA-256 fingerprint for a keystore you generated locally:
# generate a keystore (if you don't have one)
keytool -genkeypair -v -keystore my-release-key.jks -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
# print SHA-256 fingerprint
keytool -list -v -keystore my-release-key.jks -alias my-key-alias | grep 'SHA256' -A 1
- Create a TWA with Bubblewrap (recommended)
Install Bubblewrap (or use npx):
npm i -g @bubblewrap/cli
# or use: npx @bubblewrap/cli
Initialize a TWA project (example):
# Replace placeholders: YOUR_ORIGIN, com.example.yourapp, "zelo.news"
bubblewrap init --manifest https://YOUR_ORIGIN/manifest.webmanifest \
--applicationId com.example.yourapp \
--host https://YOUR_ORIGIN \
--name "zelo.news" \
--shortName "zelo" \
--output ./android-twa
# Then build the Android bundle (inside the generated project)
cd android-twa
./gradlew bundleRelease
# The produced AAB will be in app/build/outputs/bundle/release/
Notes about the Bubblewrap flow
- Bubblewrap's
initstep will ask for a few choices (splash screen color, icons). You can pass many options as flags for automation, but it's safe to run interactively. If you prefer non-interactive generation, provide flags for--applicationId,--host,--name,--launcherName. - After build, host
/.well-known/assetlinks.jsonand include your app's package name and SHA-256 fingerprint.
- Alternative: Capacitor (WebView wrapper)
If you need native plugins, Capacitor is a reasonable alternative. It's a WebView-based wrapper and not a TWA.
npm install @capacitor/cli @capacitor/core
npx cap init
# set the webDir to "dist" when prompted
npx cap add android
npx cap copy
npx cap open android
# Build and sign the AAB in Android Studio
- Sign and upload
- Use Google Play Console to upload the AAB, fill listing details, screenshots, privacy policy, and distribution.
- You can enable Google Play App Signing (recommended) or sign with your own keystore.
Checklist before upload
- Hosted origin is HTTPS and stable
manifest.webmanifestreachable and correct- Service worker registered (Lighthouse PWA checks pass)
/.well-known/assetlinks.jsonhosted and correct- AAB produced and signed
Troubleshooting
- If TWA verification fails, confirm package name and SHA-256 fingerprint in
assetlinks.jsonexactly match the signed app. - Use
adb logcatto view runtime errors when testing the app on a device.
If you want, I can:
- generate the
assetlinks.jsontemplate (done in this repo) - run Bubblewrap init against
dist/manifest.webmanifestto create anandroid-twaproject (requires JDK/Android SDK to build the AAB) - or prepare a Capacitor wrapper inside the repo
Generated on 2025-10-12
Quick helper: generate an assetlinks.json file
If you have your Android package name and the SHA-256 fingerprint of your signing key you can generate a file locally:
# from the repo root
node scripts/generate-assetlinks.js com.example.yourapp "AA:BB:CC:...:ZZ"
# result written to docs/assetlinks-generated.json
Host the generated file at: https://YOUR_ORIGIN/.well-known/assetlinks.json