# Blog Image Maintenance Guide

**Last Updated:** 2026-01-13

## Overview

This guide provides step-by-step instructions for maintaining blog images, including adding new images, generating variants, updating srcset attributes, and validating image references.

## Adding New Images

### Step 1: Download and Convert

1. **Download Image**: Add image to WordPress or download directly
2. **Convert to WebP**: Convert PNG/JPG/JPEG to WebP format (quality 85%)
3. **Store**: Place in `/v2/img/insights/` directory (physical storage)
4. **Reference**: Use public URL `/insights/bilder/filename.webp` (SEO-optimized)

### Step 2: Generate Variants (Optional)

If you need responsive variants:

```bash
# Use image processing tool (PIL/Pillow) to generate variants
# Common sizes: 300w, 768w, 1024w, 1200w, 1536w, 1920w
# Naming: image-300x184.webp (width x height) or image-300w.webp (width only)
```

**Note**: Only generate variants you actually need. Don't create variants that won't be used.

### Step 3: Update Post JSON

1. **Update Featured Image**: Set `featured_image.src` to `/insights/bilder/filename.webp`
2. **Update HTML Content**: Update `<img src>` and `srcset` attributes in HTML
3. **Update Images Array**: Add to `images[]` array if needed

### Step 4: Validate

```bash
# Check if image exists
python3 v2/scripts/blog/audit-image-files.py

# Validate all images
python3 v2/scripts/blog/validate-all-images.py --base-url http://localhost:8003
```

## Updating Srcset Attributes

### When to Update

- After adding new image variants
- After removing image variants
- When fixing broken image references
- After WordPress migration

### How to Update

**Option 1: Manual Update**

1. Edit post JSON file
2. Find `<img>` tags with `srcset` attributes
3. Update srcset to only include existing variants
4. Format: `srcset="/path/image-300x184.webp 300w, /path/image-768x471.webp 768w"`

**Option 2: Automated Fix**

```bash
# Dry run (preview changes)
python3 v2/scripts/blog/fix-srcset-references.py --dry-run

# Apply changes (creates backups automatically)
python3 v2/scripts/blog/fix-srcset-references.py
```

**Backups**: Automatically created in `docs/backups/blog-srcset-fix/`

## Validation Checklist

Before deploying blog posts:

- [ ] All image files exist in `/v2/img/insights/`
- [ ] All srcset variants exist or are removed from srcset
- [ ] Lightbox triggers have correct data attributes (`data-lightbox-src`, `data-lightbox-alt`, `data-lightbox-srcset`)
- [ ] Alpine.js expressions are complete (`x-on:click="openImageLightboxFromElement($el)"`)
- [ ] Images load correctly in lightbox (test in browser)
- [ ] Error handling works for missing images
- [ ] Validation script passes

## Common Issues and Fixes

### Issue: Lightbox Not Opening

**Symptoms**: Clicking image does nothing, console shows Alpine.js errors

**Fix**:
1. Check browser console for Alpine.js expression errors
2. Verify `x-on:click` attribute is complete (not truncated)
3. Clear browser cache (hard refresh: Cmd+Shift+R)
4. Clear PHP opcache: `php -r "opcache_reset();"`

### Issue: Images Not Loading in Lightbox

**Symptoms**: Lightbox opens but image is broken/missing

**Fix**:
1. Check image file exists in `/v2/img/insights/`
2. Verify image URL is correct (`/insights/bilder/filename.webp`)
3. Check HTTP status: `curl -I http://localhost:8003/insights/bilder/filename.webp`
4. Verify srcset variants exist if using srcset

### Issue: Missing Image Variants

**Symptoms**: Validation script reports missing variants

**Fix**:
1. Run audit: `python3 v2/scripts/blog/audit-image-files.py`
2. Check which variants are missing
3. Either generate missing variants OR remove from srcset
4. Run fix script: `python3 v2/scripts/blog/fix-srcset-references.py`
5. Validate: `python3 v2/scripts/blog/validate-all-images.py`

### Issue: Alpine.js Expression Errors

**Symptoms**: Console shows `Alpine Expression Error: Unexpected token '}'`

**Fix**:
1. Check rendered HTML for truncated `x-on:click` attributes
2. Verify `sanitizeHtmlOutput()` preserves Alpine.js attributes
3. Ensure `div`/`section` tags preserve Alpine.js attributes (already in `$allowed_tags`)
4. Clear PHP opcache and browser cache
5. Check for browser cache issues (try incognito mode)

## Maintenance Scripts

### Audit Images

```bash
python3 v2/scripts/blog/audit-image-files.py
```

**Output**: `docs/data/blog-image-audit-report.json`

**Checks**:
- All image references vs actual files
- Missing files
- Orphaned files

### Analyze Srcset Patterns

```bash
python3 v2/scripts/blog/analyze-srcset-patterns.py
```

**Output**: `docs/data/srcset-pattern-analysis.json`

**Analyzes**:
- Common variant sizes
- Naming conventions
- Missing variant patterns

### Fix Srcset References

```bash
# Preview changes
python3 v2/scripts/blog/fix-srcset-references.py --dry-run

# Apply changes
python3 v2/scripts/blog/fix-srcset-references.py
```

**Backups**: `docs/backups/blog-srcset-fix/`

**Removes**: Non-existent variants from srcset attributes

### Validate All Images

```bash
python3 v2/scripts/blog/validate-all-images.py --base-url http://localhost:8003
```

**Output**: `docs/data/image-validation-report.json`

**Checks**:
- All referenced images exist
- All srcset variants exist
- HTTP requests return 200
- Lightbox triggers work
- No Alpine.js errors

## Best Practices

### Image Optimization

- **Format**: Use WebP for all images (except SVGs)
- **Quality**: 85% WebP quality (good balance)
- **Dimensions**: Preserve original dimensions
- **Variants**: Only create variants you actually use

### Srcset Management

- **Only Reference Existing**: Never reference non-existent variants
- **Validate Before Deploy**: Run validation script before deploying
- **Remove Broken References**: Use fix script to clean up broken references
- **Keep It Simple**: Don't create more variants than needed

### Lightbox Integration

- **Data Attributes**: Always set `data-lightbox-src`, `data-lightbox-alt`, `data-lightbox-srcset`
- **Alpine.js Expression**: Use `x-on:click="openImageLightboxFromElement($el)"`
- **Error Handling**: Test error handling for missing images
- **Accessibility**: Ensure proper ARIA labels and keyboard navigation

## Related Documentation

- `docs/content/blog/guides/IMAGE_STORAGE_GUIDE.md` - Complete image storage guide
- `.cursor/rules/blog-templates.mdc` - Blog template rules and patterns
- `v2/components/blog/PostContent.php` - Image wrapping implementation
- `v2/components/blog/BlogImageLightbox.php` - Lightbox component
