- Updated README with all features: spices filter, shopping list export, clickable container legend, category prefixes - Added deployment troubleshooting for file ownership issues - Updated CLAUDE.md with architecture details, filtering logic, common issues and fixes - Added live URL reference 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pantry Inventory App
A simple web app for tracking kitchen pantry items across your household.
Live demo: https://pantry.kestrelsnest.social
Features
- Search - Instantly filter ingredients by name
- Filter tabs - View All, In Stock, Out of Stock, or Spices only
- Container filtering - Click any container type in the legend to filter by it
- Container tracking - Multiple container types organized by category with color-coded indicators
- Stock status - Mark items as in-stock or out-of-stock
- Shopping list - Tap the "Out of Stock" count to copy all out-of-stock items to clipboard
- PIN protection - Anyone can view, but editing requires a 4-digit PIN
- QR Code - Generate a scannable code to post on your pantry shelf
- OpenGraph card - Nice preview when sharing on social media
File Structure
index.html - Frontend (HTML/CSS/JS, no build step)
api.php - Backend API (reads/writes JSON files)
containers.json - Container type definitions with categories
og-image.png - OpenGraph image for social sharing
deploy - Deployment script (rsync to server)
data/ - Created automatically, excluded from git
inventory.json - Your inventory data
pin.txt - Stored PIN
Container Types
Container types are defined in containers.json and organized by category:
| Category | Types |
|---|---|
| Glass Jars | Flip Top (Large/Medium Tall/Medium Squat/Small), Canning Jar (Quart/Pint/Small) |
| Plastic Containers | OXO Large, Flip Top, Clamp Top (Large/Tall) |
| Glass Spice Jars | Hex (Large/Small), Flip Top (Tiny) |
| Other | Original Packaging |
To add container types, edit containers.json.
Deployment on YunoHost (My Webapp)
1. Install My Webapp
In YunoHost admin panel:
- Go to Applications → Install
- Search for "My Webapp"
- Configure:
- Label: Pantry
- Domain/Path: e.g.,
pantry.yourdomain.com - PHP version: 8.2 or higher
- Database: None needed
- Install
2. Upload Files
Upload to the www folder:
index.htmlapi.phpcontainers.jsonog-image.png
3. Set Permissions
The data folder needs to be writable by the web server user (typically my_webapp__X):
# SSH into your YunoHost server
cd /var/www/my_webapp__X/www
mkdir -p data
sudo chown my_webapp__X:my_webapp__X data
chmod 775 data
Important: Files in data/ must be owned by the web server user, not your admin user, or edits won't save.
4. First Use
- Visit your app URL
- Tap the lock icon → Set a 4-digit PIN
- Add your pantry items
- Share the PIN with family members who need edit access
- Print the QR code for your pantry shelf
Deploy Script
If you have SSH access, the deploy script uses rsync:
# Deploy code only (pulls current data from server)
./deploy
# Deploy code AND push local data to server
./deploy --reset-data
Edit the script to set your HOST and DIR variables.
Customization
Adding Container Types
Edit containers.json to add new categories or container types. The frontend loads this file automatically.
Changing Colors
Edit CSS variables at the top of index.html:
--cream,--warm-white- Background colors--terracotta- Accent color--forest- Primary color (buttons, active states)
Resetting Everything
Delete the data folder contents:
rm data/inventory.json data/pin.txt
Security Notes
- The PIN is stored in plain text - adequate for household use to prevent accidental edits
- Anyone with the URL can view your inventory
- For more security, put the app behind YunoHost's SSO
Troubleshooting
"Connection error" message
- Check that PHP is enabled for your My Webapp instance
- Verify the
datafolder exists and is writable
Edits not saving
- Check that
data/inventory.jsonis owned by the web server user, not your admin user - Run:
sudo chown my_webapp__X:my_webapp__X data/inventory.json
Special characters displaying as HTML entities
- The API's
sanitize()function should only trim whitespace, not HTML-encode - Re-save affected items through the UI to fix