- JavaScript 99.4%
- CSS 0.4%
- HTML 0.2%
| images | ||
| public | ||
| sample | ||
| src | fix: normalize IPv6 prefix in ip block display and submission | |
| .gitignore | ||
| CLAUDE.md | ||
| index.html | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.js | ||
| README.md | ||
| tailwind.config.js | ||
| vite.config.js | ||
wappy
wappy
A web interface for appy, a lightweight ActivityPub server built with Python and FastAPI. Also compatible with any Mastodon-compatible server.
Screenshots
wappy works with appy and any Mastodon-compatible server.
Features
- OAuth2 authentication flow (compatible with appy and Mastodon)
- Three-column layout (profile + composer / timeline / navigation + trends)
- Timelines: home, local, federated with infinite scroll
- Real-time updates via WebSocket streaming
- Composer with content warning, visibility selector, language selector, media attachments, polls and custom emojis
- Reply to posts: bottom drawer on mobile, sidebar composer prefill on desktop
- Status actions: favourite, reblog, bookmark
- Notifications: mentions, favourites, reblogs, follows, polls
- Media lightbox with keyboard navigation for images, videos and GIFs
- Profile pages with follow/unfollow, fields and post history
- Search, hashtag timelines, trends, favourites and bookmarks
- Admin panel: account management, reports, domain blocks and custom emojis
- Dark/light/auto theme
- Interface available in Catalan and English, with automatic browser language detection
- PWA support with safe area insets on mobile
Requirements
- Node.js 18 or later
- npm 9 or later
- An appy or Mastodon-compatible server
Getting Started
- Clone the repository:
git clone https://codeberg.org/spla/wappy.git
cd wappy
- Install dependencies:
npm install
- Configure the API URL. Create a
.env.localfile:
VITE_API_URL=https://your-appy-instance.example
VITE_ALLOWED_HOST=wappy.your-instance.example
If running appy locally on port 8000, skip this step — the default proxy configuration will handle it.
VITE_ALLOWED_HOST is only needed when accessing the Vite dev server from a custom domain (e.g. via nginx reverse proxy).
- Start the development server:
npm run dev
Open http://localhost:3001 in your browser.
Deployment
Development (Vite dev server)
Configure nginx to proxy to the Vite server:
server {
listen 443 ssl http2;
server_name wappy.example.net;
ssl_certificate /etc/letsencrypt/live/example.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.net/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Production (static build)
npm run build
Serve the dist/ folder with nginx:
server {
listen 443 ssl http2;
server_name wappy.example.net;
root /path/to/wappy/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
⚠️ The
try_filesdirective is required for React Router to work correctly.
Important: Vite proxy configuration
The /oauth/callback route must not be proxied — it must be handled by React Router locally. Only proxy the specific appy OAuth routes:
proxy: {
'/api': { target: apiUrl, changeOrigin: true },
'/oauth/authorize': { target: apiUrl, changeOrigin: true },
'/oauth/sign_in': { target: apiUrl, changeOrigin: true },
'/oauth/token': { target: apiUrl, changeOrigin: true },
'/oauth/revoke': { target: apiUrl, changeOrigin: true },
'/streaming': { target: apiUrl, changeOrigin: true, ws: true },
},
Built With
React Vite TanStack Query Zustand Tailwind CSS i18next
License
GNU General Public License. See the LICENSE file for details.