This commit is contained in:
echo 2026-07-24 04:02:04 +02:00
parent 8026a25278
commit 865e3c5255
22 changed files with 1224 additions and 8 deletions

286
PLAY_STORE_CHECKLIST.md Normal file
View File

@ -0,0 +1,286 @@
# Google Play Store Pre-Upload Checklist
Use this checklist before uploading to Google Play Store to ensure everything is ready.
---
## 📋 Phase 1: Assets & Content
### Icons
- [x] ✅ PNG icons generated (72, 96, 128, 144, 152, 192, 384, 512)
- [x] ✅ Maskable icon created (512x512 with safe zone)
- [x] ✅ Adaptive icon layers (foreground + background)
- [x] ✅ Icons added to manifest
**Location:** `pwa/public/icons/`
### Screenshots
- [ ] ⏳ Captured minimum 2 screenshots (recommended 4-8)
- [ ] ⏳ Screenshots are 1080x2340 (portrait)
- [ ] ⏳ Screenshots show actual app content
- [ ] ⏳ Screenshots saved as PNG
- [ ] ⏳ Screenshots named `screenshot-1.png`, `screenshot-2.png`, etc.
**Location:** `pwa/public/screenshots/`
**Guide:** See `pwa/public/screenshots/README.md`
### Feature Graphic
- [x] ✅ Created 1024x500 banner
- [x] ✅ No transparency (solid background)
- [x] ✅ Saved as PNG
**Location:** `pwa/public/assets/feature-graphic.png`
### Privacy Policy
- [x] ✅ Privacy policy written
- [x] ✅ Route added to PWA (`/privacy-policy`)
- [x] ✅ Accessible at `https://app.placebo.mk/privacy-policy`
- [x] ✅ Covers data collection (PostHog, cache, etc.)
- [x] ✅ GDPR compliant
**URL:** https://app.placebo.mk/privacy-policy
---
## 🔧 Phase 2: Technical Setup
### PWA Configuration
- [x] ✅ Manifest updated with PNG icons
- [x] ✅ Categories added (`news`, `entertainment`)
- [x] ✅ Orientation set to `portrait-primary`
- [x] ✅ Theme colors configured
- [x] ✅ Service worker working
- [x] ✅ Offline functionality tested
**File:** `pwa/vite.config.ts`
### Digital Asset Links
- [x] ✅ `assetlinks.json` template created
- [ ] ⏳ SHA256 fingerprint updated (after PWABuilder)
- [x] ✅ Nginx configured to serve `.well-known/`
- [ ] ⏳ File accessible at `https://app.placebo.mk/.well-known/assetlinks.json`
- [ ] ⏳ Validated with Google's tool
**File:** `pwa/public/.well-known/assetlinks.json`
**Validator:** https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://app.placebo.mk
### Build & Deployment
- [x] ✅ TypeScript check passes
- [x] ✅ ESLint passes
- [x] ✅ Production build successful
- [ ] ⏳ Updated PWA deployed to `https://app.placebo.mk`
- [ ] ⏳ PWA accessible and working
**Commands:**
```bash
cd pwa
npm run type-check
npm run lint
npm run build
# Deploy to Coolify
```
---
## 📱 Phase 3: Android App Generation
### PWABuilder Setup
- [ ] ⏳ PWA URL entered: `https://app.placebo.mk`
- [ ] ⏳ PWA score checked (should be high)
- [ ] ⏳ Package configured:
- App name: `Placebo.mk`
- Package ID: `mk.placebo.app`
- Launch URL: `https://app.placebo.mk/`
- Theme color: `#000000`
- Background: `#ffffff`
- Orientation: `portrait`
### Signing Key
- [ ] ⏳ Signing method chosen (Cloud or Own)
- [ ] ⏳ Signing key generated
- [ ] ⏳ SHA256 fingerprint copied
- [ ] ⏳ Signing details saved securely
⚠️ **IMPORTANT:** Keep signing key details secure! You'll need them for updates.
### App Package
- [ ] ⏳ AAB file downloaded
- [ ] ⏳ Test APK downloaded (optional)
- [ ] ⏳ SHA256 fingerprint added to `assetlinks.json`
- [ ] ⏳ Updated PWA redeployed
---
## 🧪 Phase 4: Testing (Optional but Recommended)
### Local Testing
- [ ] ⏳ APK installed on device
- [ ] ⏳ App opens without browser UI (TWA verified)
- [ ] ⏳ Navigation works correctly
- [ ] ⏳ Offline mode works
- [ ] ⏳ Analytics (PostHog) fires
- [ ] ⏳ No crashes or errors
### PWA Testing
- [ ] ⏳ Manifest validates: https://manifest-validator.appspot.com/
- [ ] ⏳ Service worker registers
- [ ] ⏳ Icons display correctly
- [ ] ⏳ Privacy policy loads
- [ ] ⏳ All routes work
---
## 🏪 Phase 5: Google Play Console Setup
### Account & App
- [x] ✅ Google Play Developer account active
- [ ] ⏳ App created in Play Console
- [ ] ⏳ App name set: `Placebo.mk`
- [ ] ⏳ Default language: Macedonian (mk-MK)
- [ ] ⏳ Free app selected
### Store Listing
- [ ] ⏳ Short description written (max 80 chars)
- [ ] ⏳ Full description written (max 4000 chars)
- [ ] ⏳ Screenshots uploaded (2-8 images)
- [ ] ⏳ Feature graphic uploaded
- [ ] ⏳ App icon uploaded (512x512)
- [ ] ⏳ Category selected: News & Magazines
- [ ] ⏳ Contact email: `privacy@placebo.mk`
- [ ] ⏳ Website: `https://placebo.mk`
- [ ] ⏳ Privacy policy URL: `https://app.placebo.mk/privacy-policy`
### Content Rating
- [ ] ⏳ Content rating questionnaire completed
- [ ] ⏳ Category: News & Reference
- [ ] ⏳ Questions answered honestly
- [ ] ⏳ Ratings applied
### Target Audience
- [ ] ⏳ Target age selected (13+ or 18+)
- [ ] ⏳ Ads declaration completed
- [ ] ⏳ Target audience declaration submitted
### Countries & Pricing
- [ ] ⏳ Countries selected (North Macedonia + others)
- [ ] ⏳ Pricing set to Free
- [ ] ⏳ Distribution settings confirmed
### App Release
- [ ] ⏳ AAB file uploaded
- [ ] ⏳ Upload processed successfully
- [ ] ⏳ Supported devices shown
- [ ] ⏳ Release notes added (Macedonian + English)
- [ ] ⏳ Release reviewed
---
## ✅ Final Checks Before Submission
### Critical Items
- [ ] ⏳ All Play Console sections marked complete (green checkmarks)
- [ ] ⏳ No errors or warnings in Play Console
- [ ] ⏳ Privacy policy accessible
- [ ] ⏳ Digital Asset Links verified
- [ ] ⏳ PWA live at `https://app.placebo.mk`
- [ ] ⏳ Screenshots captured and uploaded
- [ ] ⏳ Feature graphic uploaded
- [ ] ⏳ Content rating assigned
- [ ] ⏳ AAB uploaded successfully
### Nice to Have
- [ ] ⏳ Test APK installed and working
- [ ] ⏳ App preview video (optional)
- [ ] ⏳ Promo graphics (optional)
- [ ] ⏳ Social media announcement prepared
- [ ] ⏳ Website updated with app link
---
## 🚀 Submission
When all items above are complete:
1. [ ] ⏳ Click "Review release" in Play Console
2. [ ] ⏳ Fix any issues highlighted
3. [ ] ⏳ Click "Start rollout to Production"
4. [ ] ⏳ Confirm submission
5. [ ] ⏳ Wait for Google's review (1-7 days)
---
## 📊 Post-Submission
After submitting:
- [ ] ⏳ Monitor Play Console for review status
- [ ] ⏳ Check email for Google notifications
- [ ] ⏳ Prepare announcement content
- [ ] ⏳ Set up monitoring for crashes/errors
When approved:
- [ ] ⏳ Announce on social media
- [ ] ⏳ Update website with Play Store badge
- [ ] ⏳ Email users about app availability
- [ ] ⏳ Monitor reviews and respond
- [ ] ⏳ Track analytics and downloads
---
## 🆘 If Something Goes Wrong
### Common Issues:
**Upload fails:**
- Check AAB file size (max 150MB)
- Verify signing key
- Try uploading again
**TWA doesn't work:**
- Verify SHA256 fingerprint
- Check assetlinks.json URL
- Wait 5-10 minutes for cache
**App rejected:**
- Read rejection reason carefully
- Fix issues
- Resubmit
**Privacy policy error:**
- Ensure URL is accessible
- Check HTTPS is working
- Verify content is complete
---
## 📁 Important File Locations
| Item | Location |
|------|----------|
| Icons | `pwa/public/icons/icon-*.png` |
| Maskable Icon | `pwa/public/icons/icon-512-maskable.png` |
| Screenshots | `pwa/public/screenshots/` |
| Feature Graphic | `pwa/public/assets/feature-graphic.png` |
| Privacy Policy | `pwa/src/components/routes/PrivacyPolicyComponent.tsx` |
| Asset Links | `pwa/public/.well-known/assetlinks.json` |
| Nginx Config | `pwa/nginx.conf` |
| Manifest Config | `pwa/vite.config.ts` |
---
## 📚 Resources
- **Full Guide:** See `PLAY_STORE_GUIDE.md` in project root
- **Screenshots Guide:** See `pwa/public/screenshots/README.md`
- **Asset Links Guide:** See `pwa/public/.well-known/README.md`
- **PWABuilder:** https://www.pwabuilder.com/
- **Play Console:** https://play.google.com/console
---
**Current Status:** Ready for screenshot capture and PWABuilder packaging
**Next Action:** Capture screenshots from deployed PWA
Good luck! 🎉

490
PLAY_STORE_GUIDE.md Normal file
View File

@ -0,0 +1,490 @@
# Google Play Store Publishing Guide
Complete step-by-step guide for publishing Placebo.mk PWA to Google Play Store using PWABuilder.
---
## Prerequisites Checklist
Before starting, ensure you have:
- [x] ✅ PWA deployed and accessible at `https://app.placebo.mk`
- [x] ✅ Privacy Policy accessible at `https://app.placebo.mk/privacy-policy`
- [x] ✅ PNG icons generated (72px - 512px)
- [x] ✅ Maskable icon (512x512)
- [x] ✅ Feature graphic (1024x500) at `pwa/public/assets/feature-graphic.png`
- [ ] ⏳ Screenshots captured (see `pwa/public/screenshots/README.md`)
- [x] ✅ Google Play Developer account ($25 one-time fee)
---
## Part 1: Capture Screenshots
**Time estimate:** 15-30 minutes
### Instructions:
1. Open Chrome browser
2. Navigate to `https://app.placebo.mk`
3. Press `F12` → Click device toolbar (or `Ctrl+Shift+M`)
4. Select device: **Pixel 5** (1080 x 2340)
5. Capture these screens:
- Homepage (hero article + latest articles)
- Article detail page
- Archive page
- Live blogs page
- Category page (Sport/Art/Science)
- Any other unique feature
6. Click three dots in device toolbar → "Capture screenshot"
7. Save as `screenshot-1.png`, `screenshot-2.png`, etc.
8. Place in `pwa/public/screenshots/`
**Requirements:**
- Minimum 2 screenshots
- Recommended 4-8 screenshots
- Format: PNG
- Portrait orientation (1080x2340)
---
## Part 2: Generate Android App with PWABuilder
**Time estimate:** 20-30 minutes
### Step 1: Access PWABuilder
1. Go to https://www.pwabuilder.com/
2. Enter your PWA URL: `https://app.placebo.mk`
3. Click "Start"
### Step 2: Review PWA Score
PWABuilder will analyze your PWA and show a score. You should see:
- ✅ Manifest detected
- ✅ Service Worker registered
- ✅ HTTPS enabled
- ✅ Icons present
If any checks fail, fix them before proceeding.
### Step 3: Package for Android
1. Click "Package For Stores"
2. Select **Android** platform
3. Click "Generate Package"
### Step 4: Configure Android Settings
Fill in the following:
| Field | Value |
|-------|-------|
| **App Name** | `Placebo.mk` |
| **Package ID** | `mk.placebo.app` |
| **Launch URL** | `https://app.placebo.mk/` |
| **Display Mode** | `standalone` |
| **Theme Color** | `#000000` |
| **Background Color** | `#ffffff` |
| **Orientation** | `portrait` |
| **Icon URL** | `https://app.placebo.mk/icons/icon-512.png` |
| **Maskable Icon URL** | `https://app.placebo.mk/icons/icon-512-maskable.png` |
| **Shortcuts** | Leave empty (optional) |
| **Splash Screen** | Auto-generated from icon |
### Step 5: Signing Options
Choose **one** of these options:
#### Option A: Use PWABuilder Cloud Signing (Recommended)
**Pros:** Easy, no setup, signing key managed for you
**Cons:** Key stored by PWABuilder (trusted service)
1. Select "Use new signing key"
2. PWABuilder will generate and store your key
3. Download the signing details (keep secure!)
#### Option B: Use Your Own Signing Key
**Pros:** Full control over signing key
**Cons:** More complex, must manage keystore securely
1. Generate keystore locally:
```bash
keytool -genkey -v -keystore placebo-release.keystore \
-alias placebo-key -keyalg RSA -keysize 2048 -validity 10000
```
2. Upload keystore to PWABuilder
3. Enter keystore password and alias
### Step 6: Generate Package
1. Click "Generate Package"
2. Wait 2-5 minutes for build to complete
3. Download the generated package (AAB or APK)
### Step 7: Extract SHA256 Fingerprint
PWABuilder will show your SHA256 fingerprint. It looks like:
```
14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E3:6D:3A:AE:4E:9F:5F:E8:E3:91:A0:7E
```
**IMPORTANT:** Copy this fingerprint - you'll need it for Digital Asset Links.
---
## Part 3: Update Digital Asset Links
**Time estimate:** 5-10 minutes
### Step 1: Update assetlinks.json
1. Open `pwa/public/.well-known/assetlinks.json`
2. Replace `PLACEHOLDER_SHA256_FINGERPRINT_FROM_PWABUILDER` with your actual fingerprint
3. Save the file
Example:
```json
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "mk.placebo.app",
"sha256_cert_fingerprints": [
"14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E3:6D:3A:AE:4E:9F:5F:E8:E3:91:A0:7E"
]
}
}
```
### Step 2: Deploy Updated PWA
Rebuild and deploy your PWA with the updated assetlinks.json:
```bash
cd pwa
npm run build
# Deploy to Coolify or your hosting platform
```
### Step 3: Verify Deployment
Check that the file is accessible:
```bash
curl https://app.placebo.mk/.well-known/assetlinks.json
```
Validate with Google:
```bash
curl "https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://app.placebo.mk"
```
You should see your statement without errors.
---
## Part 4: Test Locally (Optional but Recommended)
**Time estimate:** 15-20 minutes
### Step 1: Install APK
PWABuilder provides a test APK. Install it on your Android device:
```bash
adb install -r placebo-mk.apk
```
Or email the APK to yourself and install manually.
### Step 2: Test Functionality
Verify:
- ✅ App opens without browser UI (TWA verification)
- ✅ Icons display correctly
- ✅ Offline mode works
- ✅ Navigation works
- ✅ PostHog analytics fires
- ✅ Deep links work (if applicable)
### Step 3: Debug Issues
If TWA doesn't work (shows browser UI):
- Check assetlinks.json is accessible
- Verify SHA256 fingerprint matches
- Ensure package name is correct
- Wait 5-10 minutes for DNS/CDN propagation
---
## Part 5: Upload to Google Play Console
**Time estimate:** 30-60 minutes
### Step 1: Create App in Play Console
1. Go to https://play.google.com/console
2. Click "Create app"
3. Fill in details:
- **App name:** Placebo.mk
- **Default language:** Macedonian (mk-MK)
- **App or game:** App
- **Free or paid:** Free
4. Accept declarations
5. Click "Create app"
### Step 2: Complete Store Listing
Navigate to **Store presence → Main store listing**
Fill in:
**App Details:**
- **App name:** Placebo.mk
- **Short description:** (max 80 chars)
```
Сатирични вести од Македонија - непристојно искрено и секогаш без филтер
```
- **Full description:** (max 4000 chars)
```
Placebo.mk е платформа за сатирични вести и коментари за локални и глобални настани во Македонија.
🎯 Што нудиме:
• Свежи сатирични вести за тековни настани
• Непристоен и директен коментар без филтер
• Live блогови за разбивачки вести во реално време
• Offline пристап до сите статии
• Категории: Политика, Спорт, Уметност, Наука и повеќе
⚡ Карактеристики:
• Брзо и лесно читање на статии
• Работи offline - читајте и без интернет
• Push известувања за нови статии
• Делете статии на социјални медиуми
• Темна и светла тема
Затоа што понекогаш вистината боли повеќе од фикцијата.
Следете не на web: https://placebo.mk
```
**Graphics:**
- Upload screenshots (2-8 images from `pwa/public/screenshots/`)
- Upload feature graphic (`pwa/public/assets/feature-graphic.png`)
- Upload app icon (512x512 from `pwa/public/icons/icon-512.png`)
**Categorization:**
- **App category:** News & Magazines
- **Tags:** news, satire, macedonia, politics (optional)
**Contact Details:**
- **Email:** privacy@placebo.mk (or your support email)
- **Website:** https://placebo.mk
- **Phone:** (optional)
**Privacy Policy:**
- **Privacy policy URL:** `https://app.placebo.mk/privacy-policy`
### Step 3: Set Up Content Rating
Navigate to **Policy → App content → Content rating**
1. Click "Start questionnaire"
2. Enter email address
3. Select category: **News & Reference**
4. Answer questions honestly:
- Does app contain violence? → (Select based on your content)
- Sexual content? → (Select based on your content)
- Language? → (Select based on your content)
- Drugs/alcohol references? → (Select based on your content)
5. Submit questionnaire
6. Apply ratings
### Step 4: Configure Target Audience
Navigate to **Policy → App content → Target audience and content**
1. **Target age:** 13+ (or 18+ if mature satire)
2. **App includes ads:** No (unless you add ads later)
3. Complete declaration
### Step 5: Select Countries
Navigate to **Release → Production → Countries/Regions**
1. Add countries:
- ✅ North Macedonia (primary)
- ✅ Other countries (optional - consider Albania, Serbia, Bulgaria, Greece for diaspora)
2. Click "Add countries/regions"
### Step 6: Upload AAB File
Navigate to **Release → Production → Create new release**
1. Click "Upload" and select the AAB file from PWABuilder
2. Wait for processing (may take 5-15 minutes)
3. Google Play will show:
- ✅ APK size
- ✅ Supported devices
- ✅ Permissions required
4. Review and confirm
### Step 7: Add Release Notes
Add release notes for the first version:
**Macedonian:**
```
Прва верзија на Placebo.mk апликацијата!
• Читајте сатирични вести од Македонија
• Offline пристап до содржини
• Live блогови за разбивачки настани
• Брз и едноставен интерфејс
```
**English (optional):**
```
First version of Placebo.mk app!
• Read satirical news from Macedonia
• Offline access to content
• Live blogs for breaking news
• Fast and simple interface
```
### Step 8: Review and Publish
1. Click "Review release"
2. Google will check for issues:
- ✅ All required fields complete
- ✅ Content rating assigned
- ✅ Target audience set
- ✅ Privacy policy accessible
3. Fix any warnings
4. Click "Start rollout to Production"
---
## Part 6: Wait for Review
**Time estimate:** 1-7 days
### What Happens Next:
1. **Submitted:** Your app enters Google's review queue
2. **Under Review:** Google reviews your app (usually 1-3 days)
3. **Approved:** App goes live on Play Store 🎉
4. **Rejected:** Fix issues and resubmit
### Common Rejection Reasons:
- ❌ Privacy policy not accessible
- ❌ Content rating doesn't match app content
- ❌ Misleading app description
- ❌ Copyright/trademark issues
- ❌ Broken functionality
### Tracking Status:
- Check Play Console dashboard
- You'll receive email notifications for status changes
- View detailed feedback in "Policy status"
---
## Part 7: Post-Publication
### After Your App is Live:
1. **Share the News!**
- Announce on your website
- Share on social media
- Email your users
2. **Monitor Performance:**
- Track downloads in Play Console
- Monitor crash reports
- Review user feedback/ratings
3. **Set Up Store Listing Experiments (Optional):**
- Test different screenshots
- A/B test descriptions
- Optimize icon designs
4. **Plan Updates:**
- Regular feature updates
- Bug fixes
- New content
5. **Respond to Reviews:**
- Reply to user reviews (especially negative ones)
- Show you care about user feedback
---
## Troubleshooting
### PWA Score is Low
- Verify manifest.json is valid
- Check service worker is registered
- Ensure HTTPS is enabled
- Add required icons
### TWA Verification Fails
- Double-check SHA256 fingerprint
- Verify assetlinks.json is at correct URL
- Ensure package name matches exactly
- Wait for CDN cache to clear (5-10 mins)
### Upload Failed
- Check AAB file size (max 150MB)
- Verify signing key is valid
- Ensure version code is unique
- Try uploading again (sometimes glitches occur)
### App Rejected
- Read rejection reason carefully
- Fix issues listed
- Update AAB and resubmit
- Contact Google Play support if unclear
---
## Important Files Reference
| File | Location | Purpose |
|------|----------|---------|
| Icons (PNG) | `pwa/public/icons/icon-*.png` | App icons |
| Maskable Icon | `pwa/public/icons/icon-512-maskable.png` | Adaptive icon |
| Screenshots | `pwa/public/screenshots/` | Play Store listing |
| Feature Graphic | `pwa/public/assets/feature-graphic.png` | Store banner |
| Privacy Policy | `https://app.placebo.mk/privacy-policy` | Required legal doc |
| Asset Links | `pwa/public/.well-known/assetlinks.json` | TWA verification |
| Manifest | `https://app.placebo.mk/manifest.webmanifest` | PWA config |
---
## Support & Resources
- **PWABuilder Docs:** https://docs.pwabuilder.com/
- **Google Play Help:** https://support.google.com/googleplay/android-developer/
- **TWA Guide:** https://developers.google.com/web/android/trusted-web-activity
- **Digital Asset Links:** https://developers.google.com/digital-asset-links/
---
## Next Steps After This Guide
1. ✅ Complete all phases
2. ✅ Deploy updated PWA with assetlinks.json
3. ✅ Capture screenshots
4. ✅ Generate Android app with PWABuilder
5. ✅ Upload to Google Play Console
6. ⏳ Wait for approval
7. 🎉 Celebrate when live!
Good luck! 🚀

View File

@ -48,6 +48,15 @@ http {
# Security headers for frontend # Security headers for frontend
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://eu-assets.i.posthog.com; style-src 'self' 'unsafe-inline'; style-src-elem 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://api.placebo.mk https://cms.placebo.mk https://app.placebo.mk wss://api.placebo.mk https://eu.i.posthog.com https://eu-assets.i.posthog.com; manifest-src 'self';" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://eu-assets.i.posthog.com; style-src 'self' 'unsafe-inline'; style-src-elem 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://api.placebo.mk https://cms.placebo.mk https://app.placebo.mk wss://api.placebo.mk https://eu.i.posthog.com https://eu-assets.i.posthog.com; manifest-src 'self';" always;
# Digital Asset Links for Android TWA
location /.well-known/ {
default_type application/json;
add_header Content-Type application/json;
add_header Access-Control-Allow-Origin *;
expires -1;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# Handle React Router # Handle React Router
location / { location / {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;

View File

@ -0,0 +1,104 @@
# Digital Asset Links Configuration
This file enables Trusted Web Activity (TWA) verification for the Placebo.mk Android app.
## What is this?
Digital Asset Links allows your Android app to open without browser UI by proving you own both the website (`https://app.placebo.mk`) and the Android app (`mk.placebo.app`).
## Current Status
⚠️ **PLACEHOLDER** - The SHA256 fingerprint needs to be updated after PWABuilder generates your signing key.
## How to Update
### Step 1: Generate Android App with PWABuilder
1. Go to https://www.pwabuilder.com/
2. Enter your PWA URL: `https://app.placebo.mk`
3. Click "Package For Stores" → "Android"
4. Download the package
### Step 2: Get SHA256 Fingerprint
PWABuilder will provide the SHA256 fingerprint in the downloaded package. Look for:
- `assetlinks.json` file in the package
- Or in the PWABuilder dashboard under "Android Package Options"
The fingerprint looks like:
```
14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E3:6D:3A:AE:4E:9F:5F:E8:E3:91:A0:7E
```
### Step 3: Update assetlinks.json
Replace `PLACEHOLDER_SHA256_FINGERPRINT_FROM_PWABUILDER` in `assetlinks.json` with your actual fingerprint:
```json
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "mk.placebo.app",
"sha256_cert_fingerprints": [
"14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E3:6D:3A:AE:4E:9F:5F:E8:E3:91:A0:7E"
]
}
}
```
### Step 4: Deploy Updated File
The file must be accessible at:
```
https://app.placebo.mk/.well-known/assetlinks.json
```
Nginx is already configured to serve this file (see `nginx.conf`).
### Step 5: Verify
Use Google's validator tool:
```bash
curl "https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://app.placebo.mk&relation=delegate_permission/common.handle_all_urls"
```
Or visit:
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://app.placebo.mk
You should see your statement returned with `"debugString": "*** ERRORS parsing assetlinks.json: ..."` until you replace the placeholder.
## Troubleshooting
### File not accessible
- Check nginx configuration includes `.well-known` location
- Verify file permissions (should be readable)
- Test with: `curl https://app.placebo.mk/.well-known/assetlinks.json`
### TWA not opening properly
- Ensure SHA256 fingerprint matches your app's signing certificate
- Verify package name is exactly `mk.placebo.app`
- Check both production and debug fingerprints if testing locally
### Multiple Fingerprints
If you have both debug and release keys, add both:
```json
"sha256_cert_fingerprints": [
"14:6D:E9:... (release key)",
"AA:BB:CC:... (debug key)"
]
```
## Important Notes
- This file must be served with `Content-Type: application/json`
- The file must be accessible via HTTPS (HTTP will fail)
- Changes take effect immediately (no cache)
- Keep your signing key secure - anyone with it can create apps verified for your domain
## Resources
- [Digital Asset Links Documentation](https://developers.google.com/digital-asset-links/v1/getting-started)
- [TWA Guide](https://developers.google.com/web/android/trusted-web-activity)
- [PWABuilder Documentation](https://docs.pwabuilder.com/)

View File

@ -0,0 +1,12 @@
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "mk.placebo.app",
"sha256_cert_fingerprints": [
"PLACEHOLDER_SHA256_FINGERPRINT_FROM_PWABUILDER"
]
}
}
]

Binary file not shown.

BIN
pwa/public/favicon.png Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,88 @@
# Screenshots for Google Play Store
## Required Screenshots
You need to capture **2-8 screenshots** from the deployed PWA at https://app.placebo.mk
### How to Capture Screenshots
#### Using Chrome DevTools (Recommended)
1. Open Chrome browser
2. Navigate to https://app.placebo.mk
3. Press `F12` to open DevTools
4. Click the device toolbar icon (or press `Ctrl+Shift+M`)
5. Select device: **Pixel 5** (1080 x 2340)
6. Capture each screen:
- Click the three dots menu in device toolbar
- Select "Capture screenshot"
- Save as PNG in this directory
#### Recommended Screenshots
Capture these key screens (in order):
1. **screenshot-1-home.png** - Homepage with hero article and latest articles
2. **screenshot-2-article.png** - Article detail page showing full article
3. **screenshot-3-archive.png** - Archive page with article grid
4. **screenshot-4-live-blogs.png** - Live blogs listing page
5. **screenshot-5-live-blog-detail.png** - Live blog detail with real-time updates
6. **screenshot-6-categories.png** - Category page (Sport/Art/Science)
### Google Play Requirements
- **Format**: PNG or JPEG (PNG recommended)
- **Minimum dimensions**: 320px (shortest edge)
- **Maximum dimensions**: 3840px (longest edge)
- **Aspect ratio**: 16:9 or 9:16 recommended
- **File size**: Under 8MB per screenshot
- **Quantity**: Minimum 2, maximum 8
### Current Device Settings
Using **Pixel 5** emulation:
- Resolution: 1080 x 2340 pixels
- Pixel ratio: 2.75
- Portrait orientation
- This meets Google Play requirements perfectly
### After Capturing
Once you've captured the screenshots:
1. Name them as: `screenshot-1.png`, `screenshot-2.png`, etc.
2. Place them in this directory (`pwa/public/screenshots/`)
3. Optionally add them to the PWA manifest for better install UX
4. Upload to Google Play Console when creating the app listing
### Optional: Add to Manifest
If you want screenshots to appear in the browser install prompt, update `vite.config.ts`:
```typescript
manifest: {
// ... other config
screenshots: [
{
src: '/screenshots/screenshot-1.png',
sizes: '1080x2340',
type: 'image/png',
form_factor: 'narrow',
label: 'Homepage with latest articles',
},
// Add more screenshots here
],
}
```
### Tips for Great Screenshots
- ✅ Use actual content (not Lorem Ipsum)
- ✅ Show the app in use with real articles
- ✅ Capture different sections to show variety
- ✅ Make sure text is readable
- ✅ Use light mode (default theme)
- ✅ Clear navigation bar and UI elements
- ❌ Don't include device frames (Google Play adds them)
- ❌ Don't add text overlays (save for marketing images)
- ❌ Don't capture error states or empty screens

View File

@ -0,0 +1,185 @@
export function PrivacyPolicyComponent() {
return (
<div className="max-w-4xl mx-auto py-8">
<div className="border-brutal-lg bg-card p-8">
<h1 className="font-display text-4xl md:text-5xl mb-6">Политика за приватност</h1>
<div className="font-body space-y-6 text-muted-foreground">
<p className="text-sm text-muted-foreground/70">
Последна промена: {new Date().toLocaleDateString('mk-MK', { year: 'numeric', month: 'long', day: 'numeric' })}
</p>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">1. Вовед</h2>
<p>
Добредојдовте на Placebo.mk ("ние", "наш", "нас"). Ја почитуваме вашата приватност и се посветени на заштитата на вашите лични податоци.
Оваа политика за приватност ви објаснува како собираме, користиме, чуваме и заштитуваме информации кога ја користите нашата апликација.
</p>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">2. Информации кои ги собираме</h2>
<h3 className="font-display text-xl text-foreground mb-2 mt-4">2.1 Автоматски собрани информации</h3>
<p>
Кога ја користите нашата апликација, автоматски собираме одредени информации за вашиот уред и користењето на апликацијата:
</p>
<ul className="list-disc list-inside ml-4 space-y-1 mt-2">
<li>Тип на уред и оперативен систем</li>
<li>Верзија на прелистувач</li>
<li>IP адреса</li>
<li>Времиња на пристап и употреба</li>
<li>Страници и содржина која ја прегледувате</li>
<li>Податоци за грешки и перформанси</li>
</ul>
<h3 className="font-display text-xl text-foreground mb-2 mt-4">2.2 Аналитика (PostHog)</h3>
<p>
Користиме PostHog за собирање анонимна аналитика за да го подобриме корисничкото искуство.
PostHog собира информации за тоа како ја користите апликацијата, вклучувајќи:
</p>
<ul className="list-disc list-inside ml-4 space-y-1 mt-2">
<li>Страници што ги посетувате</li>
<li>Времетраење на посета</li>
<li>Интеракции со елементи на апликацијата</li>
<li>Технички информации за вашиот уред</li>
</ul>
<p className="mt-2">
Повеќе информации за практиките за приватност на PostHog можете да најдете на{' '}
<a
href="https://posthog.com/privacy"
target="_blank"
rel="noopener noreferrer"
className="text-accent hover:underline"
>
https://posthog.com/privacy
</a>
</p>
<h3 className="font-display text-xl text-foreground mb-2 mt-4">2.3 Кеширани податоци</h3>
<p>
За да функционира offline, апликацијата кешира содржини (статии, слики) локално на вашиот уред користејќи Service Workers и browser cache.
</p>
<h3 className="font-display text-xl text-foreground mb-2 mt-4">2.4 Кориснички акаунти (доколку се применува)</h3>
<p>
Доколку создадете кориснички акаунт за администраторски функции, собираме:
</p>
<ul className="list-disc list-inside ml-4 space-y-1 mt-2">
<li>Корисничко име</li>
<li>Email адреса</li>
<li>Хеширана лозинка</li>
<li>Улога (администратор/корисник)</li>
</ul>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">3. Како ги користиме вашите податоци</h2>
<p>Вашите податоци ги користиме за:</p>
<ul className="list-disc list-inside ml-4 space-y-1 mt-2">
<li>Да ви ја обезбедиме функционалноста на апликацијата</li>
<li>Да го подобриме корисничкото искуство</li>
<li>Да анализираме како се користи апликацијата</li>
<li>Да ги идентификуваме и поправиме технички проблеми</li>
<li>Да ја заштитиме безбедноста на апликацијата</li>
<li>Да комуницираме со вас за важни промени или ажурирања</li>
</ul>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">4. Споделување на податоци</h2>
<p>
Не ги продаваме, изнајмуваме или трговаме со вашите лични податоци. Податоците може да ги споделиме само во следниве случаи:
</p>
<ul className="list-disc list-inside ml-4 space-y-1 mt-2">
<li><strong>Сервиси провајдери:</strong> PostHog за аналитика (како што е опишано погоре)</li>
<li><strong>Законски барања:</strong> Кога е законски потребно или за заштита на наши права</li>
<li><strong>Деловни трансфери:</strong> Во случај на спојување, аквизиција или продажба на средства</li>
</ul>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">5. Чување на податоци</h2>
<p>
Податоците ги чуваме онолку долго колку што е потребно за целите опишани во оваа политика.
Кеширани податоци се чуваат локално на вашиот уред и може да ги избришете преку поставките на прелистувачот.
</p>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">6. Вашите права (GDPR)</h2>
<p>Според GDPR регулативата, имате право на:</p>
<ul className="list-disc list-inside ml-4 space-y-1 mt-2">
<li><strong>Пристап:</strong> Да побарате копија од вашите лични податоци</li>
<li><strong>Корекција:</strong> Да побарате корекција на неточни податоци</li>
<li><strong>Бришење:</strong> Да побарате бришење на вашите податоци ("право на заборав")</li>
<li><strong>Ограничување:</strong> Да побарате ограничување на обработката</li>
<li><strong>Пренос:</strong> Да ги добиете податоците во структуриран, машински читлив формат</li>
<li><strong>Приговор:</strong> Да се спротивставите на обработката на вашите податоци</li>
</ul>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">7. Колачиња (Cookies)</h2>
<p>
Апликацијата користи технологии слични на колачиња (Service Workers, LocalStorage) за:
</p>
<ul className="list-disc list-inside ml-4 space-y-1 mt-2">
<li>Овозможување на offline функционалност</li>
<li>Зачувување на кориснички преференци</li>
<li>Аналитика (преку PostHog)</li>
</ul>
<p className="mt-2">
Можете да ги исклучите преку поставките на вашиот прелистувач, но тоа може да влијае на функционалноста.
</p>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">8. Безбедност</h2>
<p>
Превземаме соодветни технички и организациски мерки за заштита на вашите податоци од неовластен пристап,
промена, откривање или уништување. Меѓутоа, ниеден метод на пренос преку интернет или метод на електронско складирање
не е 100% безбеден.
</p>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">9. Деца</h2>
<p>
Нашата апликација не е наменета за деца под 13 години. Не собираме свесно лични информации од деца под 13 години.
Доколку сте родител или старател и знаете дека вашето дете ни дало лични информации, ве молиме контактирајте не.
</p>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">10. Промени на оваа политика</h2>
<p>
Може периодично да ја ажурираме оваа Политика за приватност. Ќе ве известиме за значајни промени со објавување
на новата политика на оваа страница и ажурирање на "Последна промена" датумот.
</p>
</section>
<section>
<h2 className="font-display text-2xl text-foreground mb-3">11. Контакт</h2>
<p>
Доколку имате прашања за оваа Политика за приватност или сакате да ги користите вашите права,
можете да не контактирате на:
</p>
<div className="mt-2 p-4 border-2 border-foreground bg-background">
<p><strong>Placebo.mk</strong></p>
<p>Email: <a href="mailto:privacy@placebo.mk" className="text-accent hover:underline">privacy@placebo.mk</a></p>
<p>Веб: <a href="https://placebo.mk" className="text-accent hover:underline">https://placebo.mk</a></p>
</div>
</section>
<section className="mt-8 pt-8 border-t-2 border-foreground/20">
<p className="text-sm text-muted-foreground/70">
Со користење на Placebo.mk апликацијата, се согласувате со оваа Политика за приватност.
Доколку не се согласувате со политиката, ве молиме не користете ја апликацијата.
</p>
</section>
</div>
</div>
</div>
)
}

View File

@ -11,6 +11,7 @@ import { AuthPage } from './components/routes/AuthPage'
import { SportComponent } from './components/routes/SportComponent' import { SportComponent } from './components/routes/SportComponent'
import { ArtComponent } from './components/routes/ArtComponent' import { ArtComponent } from './components/routes/ArtComponent'
import { ScienceComponent } from './components/routes/ScienceComponent' import { ScienceComponent } from './components/routes/ScienceComponent'
import { PrivacyPolicyComponent } from './components/routes/PrivacyPolicyComponent'
import { ProtectedRoute } from './components/auth/ProtectedRoute' import { ProtectedRoute } from './components/auth/ProtectedRoute'
import { Header } from './components/layout/Header' import { Header } from './components/layout/Header'
import { HeroArticle } from './components/home/HeroArticle' import { HeroArticle } from './components/home/HeroArticle'
@ -57,6 +58,7 @@ const rootRoute = createRootRoute({
<li><Link to="/art" className="hover:text-accent transition-colors">Уметност</Link></li> <li><Link to="/art" className="hover:text-accent transition-colors">Уметност</Link></li>
<li><Link to="/science" className="hover:text-accent transition-colors">Наука</Link></li> <li><Link to="/science" className="hover:text-accent transition-colors">Наука</Link></li>
<li><Link to="/archive" className="hover:text-accent transition-colors">Архива</Link></li> <li><Link to="/archive" className="hover:text-accent transition-colors">Архива</Link></li>
<li><Link to="/privacy-policy" className="hover:text-accent transition-colors">Приватност</Link></li>
</ul> </ul>
</div> </div>
<div> <div>
@ -305,6 +307,12 @@ const adminDashboardRoute = createRoute({
), ),
}) })
const privacyPolicyRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/privacy-policy',
component: PrivacyPolicyComponent,
})
const routeTree = rootRoute.addChildren([ const routeTree = rootRoute.addChildren([
indexRoute, indexRoute,
archiveRoute, archiveRoute,
@ -318,6 +326,7 @@ const routeTree = rootRoute.addChildren([
liveBlogAdminRoute, liveBlogAdminRoute,
createLiveBlogRoute, createLiveBlogRoute,
adminDashboardRoute, adminDashboardRoute,
privacyPolicyRoute,
]) ])
export const router = createRouter({ routeTree }) export const router = createRouter({ routeTree })

View File

@ -13,31 +13,64 @@ export default defineConfig({
srcDir: 'src', srcDir: 'src',
filename: 'sw.ts', filename: 'sw.ts',
registerType: 'autoUpdate', registerType: 'autoUpdate',
includeAssets: ['icons/*.svg'], includeAssets: ['icons/*.png', 'icons/*.svg'],
manifest: { manifest: {
name: 'Placebo.mk', name: 'Placebo.mk',
short_name: 'Placebo', short_name: 'Placebo',
description: 'Сатирични вести од Македонија', description: 'Сатирични вести од Македонија',
lang: 'mk', lang: 'mk',
start_url: '/', start_url: '/',
scope: '/',
display: 'standalone', display: 'standalone',
orientation: 'portrait-primary',
background_color: '#ffffff', background_color: '#ffffff',
theme_color: '#000000', theme_color: '#000000',
categories: ['news', 'entertainment'],
icons: [ icons: [
{ {
src: '/icons/icon-192.svg', src: '/icons/icon-72.png',
sizes: '72x72',
type: 'image/png',
},
{
src: '/icons/icon-96.png',
sizes: '96x96',
type: 'image/png',
},
{
src: '/icons/icon-128.png',
sizes: '128x128',
type: 'image/png',
},
{
src: '/icons/icon-144.png',
sizes: '144x144',
type: 'image/png',
},
{
src: '/icons/icon-152.png',
sizes: '152x152',
type: 'image/png',
},
{
src: '/icons/icon-192.png',
sizes: '192x192', sizes: '192x192',
type: 'image/svg+xml', type: 'image/png',
}, },
{ {
src: '/icons/icon-512.svg', src: '/icons/icon-384.png',
sizes: '512x512', sizes: '384x384',
type: 'image/svg+xml', type: 'image/png',
}, },
{ {
src: '/icons/icon-512.svg', src: '/icons/icon-512.png',
sizes: '512x512', sizes: '512x512',
type: 'image/svg+xml', type: 'image/png',
},
{
src: '/icons/icon-512-maskable.png',
sizes: '512x512',
type: 'image/png',
purpose: 'maskable', purpose: 'maskable',
}, },
], ],