- Delete eas.json and strip extra.eas.projectId from app.json - Add plugins/withAndroidReleaseSigning.js — Expo config plugin that injects release signingConfig into the generated build.gradle during expo prebuild - Add build-apk.sh — self-contained build script (expo prebuild + Gradle) Reads keystore credentials from ~/.config/postiz-mobile/signing.env Outputs APK/AAB to dist/, wipes credentials from gradle.properties after build - Add install-android-sdk.sh — one-time Android SDK cmdline-tools bootstrap - Remove unused expo-task-manager dependency - Update .gitignore: android/, ios/, static-build/ excluded (generated) Build workflow: 1. eas credentials --platform android # export keystore once 2. ./install-android-sdk.sh # first time only 3. ./build-apk.sh # → dist/postiz-mobile-YYYYMMDD-HHMM.apk Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PostizMobile
React Native (Expo) mobile app to control a self-hosted Postiz instance from your Android or iOS device.
Table of Contents
- Features
- Prerequisites
- Installation & Development
- App Configuration
- Project Architecture
- Postiz API
- Android APK Build (EAS)
- iOS Build (Expo Launch)
- Pushing Changes to Gitea
- Environment Variables & Secrets
- Troubleshooting
Features
| Screen | Description |
|---|---|
| Calendar | Monthly view with color dots per day (indigo = scheduled, green = published, red = error). Tap a day to see its posts. |
| Posts | Filtered list (All / Queue / Published / Draft / Error) with pull-to-refresh and swipe left to delete. |
| Compose | Text editor, channel picker, date/time picker, gallery image import + upload, publish now or schedule. |
| Settings | API key and base URL input, connection test, secure storage (SecureStore). |
| Notifications | Automatic local alerts when a post transitions to PUBLISHED or ERROR (polling every 15 minutes). |
Theme: forced dark (userInterfaceStyle: dark).
Authentication: API key stored in expo-secure-store, never hardcoded.
Prerequisites
| Tool | Minimum version |
|---|---|
| Node.js | 20 LTS |
| pnpm | 10+ |
| Expo Go (phone) | SDK 54 compatible |
| EAS account (for APK) | free on expo.dev |
npm install -g pnpm
npm install -g eas-cli
Installation & Development
1. Clone the repository
git clone ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
cd Postiz-android
2. Install dependencies
pnpm install
3. Start the development server
pnpm --filter @workspace/postiz-mobile run dev
The terminal displays a QR code. Scan it with Expo Go (Android) or the Camera app (iOS) to see the app live.
4. Open in the browser (web preview)
http://localhost:<PORT>
The port is dynamically assigned by the Replit environment.
App Configuration
On first launch, the Settings screen is shown because no key is configured yet.
- Base URL:
https://your-postiz-instance.fr/public/v1 - API Key: generated from your Postiz instance → Settings → API Keys
- Tap Test Connection to validate
- Tap Save Settings
The key is encrypted and stored locally via expo-secure-store. It is never sent to a third-party service.
Project Architecture
artifacts/postiz-mobile/
├── app/
│ ├── _layout.tsx # Root layout : providers, fonts, notifications
│ └── (tabs)/
│ ├── _layout.tsx # Tab bar (NativeTabs iOS 26+ / Tabs classique)
│ ├── index.tsx # Écran Calendrier
│ ├── posts.tsx # Écran Liste des posts
│ ├── compose.tsx # Écran Composer
│ └── settings.tsx # Écran Paramètres
├── components/
│ ├── ChannelChip.tsx # Chip de sélection de canal
│ ├── ErrorBoundary.tsx # Gestionnaire d'erreurs global
│ ├── PostCard.tsx # Carte post avec swipe-to-delete
│ └── StatusBadge.tsx # Badge QUEUE / PUBLISHED / ERROR / DRAFT
├── constants/
│ └── colors.ts # Palette dark theme
├── context/
│ └── PostizContext.tsx # Client axios + SecureStore (apiKey, baseUrl)
├── hooks/
│ ├── useColors.ts # Tokens couleur selon le thème
│ └── useNotifications.ts # Permissions + polling + notifications locales
├── assets/
│ └── images/
│ └── icon.png # Icône générée par IA
└── app.json # Config Expo (permissions, plugins, thème)
Main dependencies
| Package | Usage |
|---|---|
expo-router |
File-based navigation |
axios |
HTTP client for the Postiz API |
expo-secure-store |
Encrypted API key storage |
react-native-calendars |
Monthly calendar view |
@react-native-community/datetimepicker |
Date/time picker in Compose |
expo-image-picker |
Gallery photo access |
expo-notifications |
Local status notifications |
expo-task-manager |
Background task for polling |
@tanstack/react-query |
API data cache and refetch |
Postiz API
Base URL configured by the user (e.g. https://postiz.example.com/public/v1).
| Method | Endpoint | Usage |
|---|---|---|
GET |
/integrations |
List channels (Twitter, LinkedIn, etc.) |
GET |
/posts?startDate=&endDate= |
Posts over a date range |
POST |
/posts |
Create / schedule a post |
DELETE |
/posts/:id |
Delete a post |
POST |
/upload |
Upload an image (multipart) |
POST /posts payload example
{
"type": "schedule",
"date": "2025-01-15T10:00:00.000Z",
"content": [
{
"content": "Mon super post 🚀",
"image": [{ "id": "upload-id", "path": "/uploads/photo.jpg" }]
}
],
"integrations": ["integration-id-twitter", "integration-id-linkedin"]
}
To publish immediately, use "type": "now".
Android APK Build (EAS)
Prerequisites: free account on expo.dev and
eas-cliinstalled.
1. Log in to EAS
npx eas login
2. Initialize EAS in the project
cd artifacts/postiz-mobile
npx eas init
This generates a projectId in app.json.
3. EAS configuration file
Already included in the repository:
artifacts/postiz-mobile/eas.jsonis present, you can skip this step.
To recreate it manually:
{
"cli": {
"version": ">= 16.0.0"
},
"build": {
"preview": {
"android": {
"buildType": "apk"
}
},
"production": {
"android": {
"buildType": "app-bundle"
}
}
},
"submit": {
"production": {}
}
}
4. Start the APK build
# APK de test (sideload)
npx eas build --platform android --profile preview
# AAB pour le Play Store
npx eas build --platform android --profile production
The build runs in the EAS cloud (~10-15 min). At the end, EAS displays a download link and a QR code to retrieve the .apk file.
5. Install the APK on your phone
# Via adb
adb install postiz-mobile.apk
# Ou scannez le QR code affiché par EAS
6. Publish the APK as a Gitea Release
Once the .apk is downloaded from EAS, attach it to a Gitea release to make it available directly from the repository:
- Go to
https://homegit.gyozamancave.fr/billisdead/Postiz-android/releases - Click New Release
- Choose a tag (e.g.
v1.0.0) and a title - Drag and drop the
.apkfile into the attachments area - Click Publish Release
The APK will then be downloadable directly from the Gitea repository page.
Declared Android permissions
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
READ_MEDIA_IMAGES <!-- photos galerie -->
RECEIVE_BOOT_COMPLETED
VIBRATE <!-- notifications -->
iOS Build (Expo Launch)
Available only via Replit Expo Launch (automated App Store submission).
- In Replit, click the Publish button
- Select Expo Launch
- Follow the wizard (Apple Developer account required)
Note: Google Play publishing is not yet supported by Expo Launch — use EAS for Android.
Pushing Changes to Gitea
The remote repository is: ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
The SSH key used is stored in the GITEA_SSH_KEY environment variable (on the Replit side).
Push from your local machine
# Ajouter le remote (une seule fois)
git remote add gitea ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
# Pousser
git push gitea main
Make sure your public SSH key is added in Gitea → User Settings → SSH / GPG Keys.
Push from Replit (via script)
From Replit, direct git push commands are restricted. Use the bundle script:
# Créer le bundle
git bundle create /tmp/postiz.bundle main
# Cloner le bundle et pousser
git clone /tmp/postiz.bundle /tmp/repo_push
cd /tmp/repo_push
git remote add gitea ssh://gitea@homegit.gyozamancave.fr:2222/billisdead/Postiz-android.git
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_ed25519 -o StrictHostKeyChecking=no -p 2222" \
git push --force gitea main
Environment Variables & Secrets
| Variable | Storage | Description |
|---|---|---|
GITEA_SSH_KEY |
Replit Secrets (shared) | Private SSH key for pushing to Gitea |
SESSION_SECRET |
Replit Secrets | Session secret (API server) |
App-side variables (Postiz API key, URL) are entered by the user in the Settings screen and stored in expo-secure-store — they never pass through the source code.
Troubleshooting
The app shows "Not Configured" on all screens
→ Go to the Settings tab, enter your API key and URL, then tap Test Connection.
"Connection failed" in Settings
- Check that the URL ends with
/public/v1 - Check that the API key is valid (generated in Postiz → API Keys)
- Check that your Postiz instance is accessible from the internet
No notifications received
- Accept notification permissions on first launch
- Polling runs every 15 minutes — wait for a full cycle
- On Android, check that the app's notifications are not disabled in system settings
Metro error "module not found"
pnpm install
# Puis redémarrer le workflow Expo
Calendar does not load posts
- Check that the Postiz API supports
startDate/endDateparameters onGET /posts - Check network logs: in Expo Go, shake the device → Open Debugger
EAS build fails
# Vérifier la version Expo
npx expo --version
# Vérifier la cohérence des packages
npx expo install --check
Contributing
- Fork on Gitea:
https://homegit.gyozamancave.fr/billisdead/Postiz-android - Create a feature branch:
git checkout -b feature/my-feature - Commit your changes
- Push and open a Pull Request
Generated with ❤️ on Replit — PostizMobile v1.0.0