add or update alt text on your media forked from psingletary.com/verifier

Files
README.md

Altifier #

Scan your Bluesky posts for missing alt text and fix them with AI-generated descriptions.

Features #

  • Scan your posts: Enumerate all your Bluesky posts and replies, finding images that lack alt text
  • AI-powered alt text: Generates descriptive alt text using vision AI, following Section 508 guidelines
  • Review and edit: Preview generated alt text, edit inline, and approve before applying
  • Bluesky OAuth login: Authenticate securely with your Bluesky/ATProto account

What this does #

Altifier scans the image posts (app.bsky.feed.post records with app.bsky.embed.images) in your PDS, identifies images missing alt text, generates descriptions via AI, and lets you apply them by recreating your posts with alt text included.

Note: Recreating a post with alt text deletes the original and creates a new one. Likes, reposts, quotes, and replies on the original post are lost.

Development #

npm install
npm start

Build #

npm run build

The build/ directory contains the static site ready for deployment.

Deployment #

This app is a fully static React SPA and can be deployed to:

  • Wisp.place: wispctl deploy <handle> --path ./build --site altifier --spa
  • Tangled: Configure the repo's Sites settings with deploy directory /build
  • Any static host: Serve the build/ directory with SPA fallback to index.html

AI Setup #

Altifier uses Google Gemini (BYO-key) for alt text generation. The exact model lives in one place: src/utils/altGenerator.js (GEMINI_MODEL).

The key is never bundled or baked into the build. Each user pastes their own key once in the app's AI Settings; it is stored only in localStorage key altifier.geminiKey and sent directly to Google's API in the x-goog-api-key header. If no key is set, Generate buttons are hidden and manual alt-text entry still works.

Get a free API key at aistudio.google.com.

OAuth Configuration #

OAuth client metadata lives in public/client-metadata.json — the single source of truth (served at /client-metadata.json). AuthContext fetches it at startup, so there is no second copy to drift. If you change the client_id / redirect_uris / scope in that file, the OAuth flow breaks with opaque failures.

License #

MIT