Skip to content

Serve blog images via wsrv.nl CDN proxy in production#285

Merged
pftg merged 2 commits into
masterfrom
feat/cdn-image-proxy
Apr 14, 2026
Merged

Serve blog images via wsrv.nl CDN proxy in production#285
pftg merged 2 commits into
masterfrom
feat/cdn-image-proxy

Conversation

@pftg
Copy link
Copy Markdown
Member

@pftg pftg commented Apr 14, 2026

Summary

  • Fixes GitHub Pages artifact exceeding 1GB limit (was 1.28GB → now 119MB)
  • In production, image templates emit wsrv.nl proxy URLs instead of Hugo-processed local paths
  • CDN disabled by default (config/_default/), enabled only in config/production/hugo.toml
  • Dev mode (hugo server) unchanged — local image processing as before

Changes

  • Config: Added [params.cdn] with enabled, provider, rawBase — toggled per environment
  • render-image.html: CDN branch emits <picture> srcset via wsrv.nl (webp+jpeg, 400/800/1200/1600w)
  • img-cropped.html: Blog list thumbnails via wsrv.nl (retina JPG)
  • enhanced-meta-tags.html: OG images via wsrv.nl (both root layouts/ and themes/beaver/ copies)
  • img.html shortcode: Direct images via wsrv.nl
  • _hugo.yml: Strips blog media from public/blog/ after build, before artifact upload
  • Docs: docs/workflows/cdn-image-proxy.md documents both wsrv.nl and Cloudflare R2 solutions
  • Tests: 7 new CDN-specific unit tests validating URLs, formats, sizes, and dimensions

Impact

Metric Before After
Processed images 8,241 2,416 (−71%)
Artifact size 2.0 GB 119 MB (−94%)

Test plan

  • bin/rake test:critical — 42 tests, 116 assertions, 0 failures
  • Visual regression — 84 screenshots compared, 0 differences
  • CDN unit tests — 7 tests verifying wsrv.nl URLs in picture/srcset/og:image
  • Dev build (hugo --environment development) — still uses local image processing
  • Verify wsrv.nl serves images correctly on deployed site
  • Monitor GitHub Actions artifact size stays under 1GB

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • CDN-backed image proxy enabled for production to improve image delivery and reduce artifact size; development still uses local image processing
    • Build now removes blog media files from published artifacts to keep uploads small
  • Improvements

    • More consistent meta/OG/twitter image handling and picture/srcset generation for social previews and responsive images
  • Documentation

    • Added CDN image proxy configuration and setup guide
  • Tests

    • New suite validating CDN image proxying and image URL transformations

Fixes GitHub Pages artifact exceeding 1GB limit (was 1.28GB).
In production, image templates emit wsrv.nl proxy URLs instead of
Hugo-processed local paths, reducing artifact from 2GB to 119MB.

- CDN disabled by default, enabled in config/production/hugo.toml
- Templates check site.Params.cdn.enabled (per-environment config)
- Responsive images preserved: picture/srcset with webp+jpeg at 4 widths
- Blog thumbnails, OG images, shortcode images all CDN-ified
- GitHub Actions strips blog media after build
- Dev mode unchanged (hugo server works as before)
- Cloudflare R2 option documented for future use

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 14, 2026

Warning

Rate limit exceeded

@pftg has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 33 minutes and 54 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 33 minutes and 54 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cfba418f-3758-4dca-a9b1-a695047f5ece

📥 Commits

Reviewing files that changed from the base of the PR and between b630be6 and 25b1f07.

📒 Files selected for processing (23)
  • .github/actions/setup-hugo/action.yml
  • .github/workflows/_hugo.yml
  • .github/workflows/publish.yml
  • .github/workflows/test.yml
  • .gitignore
  • bin/hugo-build
  • config/_default/hugo.toml
  • docs/workflows/cdn-image-proxy.md
  • layouts/partials/seo/enhanced-meta-tags.html
  • test/unit/cdn_image_proxy_test.rb
  • themes/beaver/layouts/_markup/render-image.html
  • themes/beaver/layouts/_shortcodes/img.html
  • themes/beaver/layouts/partials/blog/img-cropped.html
  • themes/beaver/layouts/partials/blog/json-ld.html
  • themes/beaver/layouts/partials/cdn/url.html
  • themes/beaver/layouts/partials/components/testimonial.html
  • themes/beaver/layouts/partials/data/authors-cached.html
  • themes/beaver/layouts/partials/data/company-cached.html
  • themes/beaver/layouts/partials/data/testimonials-cached.html
  • themes/beaver/layouts/partials/homepage/companies.html
  • themes/beaver/layouts/partials/page/testimonials.html
  • themes/beaver/layouts/partials/seo/enhanced-meta-tags.html
  • themes/beaver/layouts/partials/technologies.html
📝 Walkthrough

Walkthrough

Adds a conditional CDN image-proxy flow (wsrv.nl) enabled for production, updates templates to emit CDN-backed image URLs when enabled, adds a CDN URL partial and tests, and changes CI/workflow to build with newer Hugo, remove blog media from the artifact, and log artifact size before upload.

Changes

Cohort / File(s) Summary
CI / Hugo Build
/.github/workflows/_hugo.yml, /.github/actions/setup-hugo/action.yml, /.github/workflows/test.yml, bin/hugo-build
Bump Hugo to 0.160.1, change default environment to production in composite action, add output-dir/base-url inputs and env handling, set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24, add post-build step to delete blog media from public/blog/ and report public/ size; test workflows set PRECOMPILED_ASSETS and custom HUGO_DEFAULT_PATH.
Site config
config/_default/hugo.toml, config/production/hugo.toml
Add [params.cdn] block with rawBase and enabled (default false) and enable CDN in production config.
CDN partial & templates
themes/beaver/layouts/partials/cdn/url.html, themes/beaver/layouts/_markup/render-image.html, themes/beaver/layouts/_shortcodes/img.html, themes/beaver/layouts/partials/blog/img-cropped.html, themes/beaver/layouts/partials/seo/enhanced-meta-tags.html, layouts/partials/seo/enhanced-meta-tags.html
Introduce cdn/url partial to construct wsrv.nl proxy URLs; branch image rendering and SEO meta generation based on site.Params.cdn.enabled to emit wsrv.nl src/srcset with appropriate query params; GIF handling and retina/resize flows adjusted.
Theme data references & caching
themes/beaver/layouts/partials/components/testimonial.html, .../data/*-cached.html, .../homepage/companies.html, .../page/testimonials.html, .../technologies.html, themes/beaver/layouts/partials/blog/json-ld.html
Switch various templates and cached partials from site.Data.* to hugo.Data.* for cache keys/data sourcing; JSON-LD publisher now reads hugo.Data.company.
Docs & Tests
docs/workflows/cdn-image-proxy.md, test/unit/cdn_image_proxy_test.rb
Add documentation describing CDN image-proxy behavior and CI cleanup; add comprehensive unit tests verifying wsrv.nl URLs, srcset variants, thumbnail/OG behavior, and dimension attributes.

Sequence Diagram(s)

sequenceDiagram
  participant CI as GitHub Actions
  participant Hugo as Hugo Build
  participant Templates as Site Templates
  participant CDN as wsrv.nl
  participant Artifact as Pages Artifact

  CI->>Hugo: run build (environment=production, params.cdn.enabled=true)
  Hugo->>Templates: render pages (templates consult site.Params.cdn)
  Templates->>CDN: construct wsrv.nl URLs via `cdn/url` partial (rawBase + resource path + params)
  Hugo->>Artifact: write `public/` (includes CDN-backed URLs, no local blog media removed yet)
  CI->>Artifact: delete image/media from `public/blog/` (post-build)
  CI->>CI: measure `public/` size
  CI->>GitHub Pages: upload artifact & deploy
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Possibly related PRs

  • jetthoughts/jetthoughts.github.io#148: Modifies the same .github/workflows/_hugo.yml workflow and related deployment steps (strong overlap in CI changes).
  • jetthoughts/jetthoughts.github.io#144: Related changes to theme image-rendering partials and responsive srcset logic (overlaps templates).
  • jetthoughts/jetthoughts.github.io#282: Touches SEO/og:image meta tag handling and sizing (overlaps meta-template edits).

Poem

🐰 I nibble at pixels, stitch raw paths tight,
I send them through wsrv with hops of delight.
CI trims the crumbs, artifacts slim and neat,
Production bounces images—fast, tidy, and sweet. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and clearly summarizes the primary change: introducing wsrv.nl CDN proxy for serving blog images in production, which directly aligns with the main objective of reducing artifact size and image processing.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cdn-image-proxy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
test/unit/cdn_image_proxy_test.rb (1)

62-65: Prefer behavior assertions over repository-specific config assertions.

Asserting host/repo strings couples the test to current config internals instead of CDN behavior. This will create unnecessary failures if rawBase changes while feature behavior remains correct.

💡 Suggested direction
-    assert_includes srcset, "raw.githubusercontent.com",
-      "CDN URLs should proxy from GitHub raw content"
-    assert_includes srcset, "jetthoughts/jetthoughts.github.io",
-      "CDN URLs should reference this repository"
+    assert_includes srcset, "wsrv.nl", "CDN URLs should use wsrv proxy host"
+    assert_match(/url=.*\/content\//, srcset, "CDN URLs should proxy source content path")

Based on learnings: Ensure test quality by focusing on behavior only; reject implementation/existence/config tests as defined in /knowledge/25.04-test-smell-prevention-enforcement-protocols.md.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/cdn_image_proxy_test.rb` around lines 62 - 65, The assertions in
cdn_image_proxy_test.rb that check for repository-specific strings
("raw.githubusercontent.com" and "jetthoughts/jetthoughts.github.io") couple the
test to config; instead, update the assertions that reference srcset to verify
CDN behavior only: remove the two repo-specific assert_includes checks and
replace them with behavior-focused assertions on srcset (e.g., assert that each
URL is rewritten/proxied by the CDN pattern or matches a proxy/hostname-regex
and/or that original upstream hostnames are not present). Target the srcset
variable in the test and use a generic proxy-pattern match or existence/absence
checks rather than repository-specific literals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@config/_default/hugo.toml`:
- Around line 56-60: The templates currently hardcode wsrv.nl, so the new
params.cdn.provider knob does nothing; update the image/SEO templates
(_shortcodes/img.html, layouts/partials/blog/img-cropped.html,
_markup/render-image.html and the SEO partials) to read
.Site.Params.cdn.provider and branch on its value (e.g., "wsrv" vs
"cloudflare"), building URLs from .Site.Params.cdn.rawBase for wsrv and from
.Site.Params.cdn.cloudflareBase for Cloudflare R2; ensure the same branching
logic is used wherever image URLs are generated or proxied, or if you prefer to
keep changes minimal remove the unused provider/cloudflare keys from params.cdn
instead of changing templates.

In `@docs/workflows/cdn-image-proxy.md`:
- Around line 45-47: Add a language identifier to the fenced code block that
contains the URL pattern (the block starting with ``` and containing
"https://wsrv.nl/?url=raw.githubusercontent.com/OWNER/REPO/BRANCH/content/PATH&w=WIDTH&output=FORMAT&q=QUALITY");
change the opening fence from ``` to ```text so the block becomes ```text ...
``` to satisfy markdownlint MD040.

In `@layouts/partials/seo/enhanced-meta-tags.html`:
- Around line 109-111: The CDN branch currently builds wsrv.nl URLs with
fit=inside (see the site.Params.cdn.enabled block and variables $rawURL and
$image) but still emits hardcoded og:image:width="1200" and
og:image:height="630"; either change the wsrv.nl query to request an exact
output (e.g., replace fit=inside with fit=cover or fit=fill so the image will be
1200x630) or compute and emit the actual output dimensions instead of the
hardcoded 1200/630 values; update every CDN occurrence (the $image construction
and the corresponding og:image:width/og:image:height outputs referenced in the
same template branches) so the URL and the published width/height are
consistent.

In `@test/unit/cdn_image_proxy_test.rb`:
- Around line 11-12: The conditional skip ("skip \"No blog posts found\" if
`@blog_posts.empty`?") masks regressions; remove that skip and make the test
deterministic by ensuring required data exists (e.g., create or load a blog post
with an og/picture before exercising the CDN proxy) or explicitly assert
expected behavior when no posts exist; update setup that populates `@blog_posts`
(or replace `@blog_posts` with a factory/fixture creation step) so the test always
exercises the CDN image proxy logic rather than silently passing when
`@blog_posts` is empty.

In `@themes/beaver/layouts/partials/seo/enhanced-meta-tags.html`:
- Around line 213-217: The CDN branch currently hardcodes $imageWidth="1200" and
$imageHeight="630" which can be inaccurate because wsrv.nl may return smaller
images; update the logic in the site.Params.cdn.enabled branch to either derive
real dimensions from the Hugo resource (use the page resource's .Width and
.Height for the file referenced by $resource or $page.File/ resource) and set
$imageWidth/$imageHeight from those values, or remove the og:image:width and
og:image:height meta tags entirely for the CDN case; apply the same change to
the non-CDN image branch that sets $imageWidth/$imageHeight (the other block
around lines 232–236) so both branches use real resource dimensions or omit the
width/height assertions.

---

Nitpick comments:
In `@test/unit/cdn_image_proxy_test.rb`:
- Around line 62-65: The assertions in cdn_image_proxy_test.rb that check for
repository-specific strings ("raw.githubusercontent.com" and
"jetthoughts/jetthoughts.github.io") couple the test to config; instead, update
the assertions that reference srcset to verify CDN behavior only: remove the two
repo-specific assert_includes checks and replace them with behavior-focused
assertions on srcset (e.g., assert that each URL is rewritten/proxied by the CDN
pattern or matches a proxy/hostname-regex and/or that original upstream
hostnames are not present). Target the srcset variable in the test and use a
generic proxy-pattern match or existence/absence checks rather than
repository-specific literals.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c1a9d72d-b20d-42f6-88d7-1894c273d46f

📥 Commits

Reviewing files that changed from the base of the PR and between 89ef452 and 57bd0c2.

📒 Files selected for processing (10)
  • .github/workflows/_hugo.yml
  • config/_default/hugo.toml
  • config/production/hugo.toml
  • docs/workflows/cdn-image-proxy.md
  • layouts/partials/seo/enhanced-meta-tags.html
  • test/unit/cdn_image_proxy_test.rb
  • themes/beaver/layouts/_markup/render-image.html
  • themes/beaver/layouts/_shortcodes/img.html
  • themes/beaver/layouts/partials/blog/img-cropped.html
  • themes/beaver/layouts/partials/seo/enhanced-meta-tags.html

Comment thread config/_default/hugo.toml Outdated
Comment thread docs/workflows/cdn-image-proxy.md Outdated
Comment thread layouts/partials/seo/enhanced-meta-tags.html Outdated
Comment thread test/unit/cdn_image_proxy_test.rb Outdated
Comment thread themes/beaver/layouts/partials/seo/enhanced-meta-tags.html Outdated
@pftg pftg force-pushed the feat/cdn-image-proxy branch 4 times, most recently from fc09a77 to afb0ce2 Compare April 14, 2026 08:26
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
docs/workflows/cdn-image-proxy.md (1)

32-35: Add a language identifier to the fenced code block.

The code block is missing a language specifier, triggering markdownlint MD040.

💡 Suggested fix
-```
+```text
 {{ partial "cdn/url" (dict "page" $page "resource" $resource "params" "w=400&output=webp&q=80") }}
 → "https://wsrv.nl/?url=raw.githubusercontent.com/.../image.jpg&w=400&output=webp&q=80"
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @docs/workflows/cdn-image-proxy.md around lines 32 - 35, Add a language
identifier (for example "text") to the fenced code block that contains the {{
partial "cdn/url" (dict "page" $page "resource" $resource "params"
"w=400&output=webp&q=80") }} snippet and the arrowed example so markdownlint
MD040 is resolved; update the opening fence from totext and keep the
closing fence as ``` with no other content changes.


</details>

</blockquote></details>
<details>
<summary>test/unit/cdn_image_proxy_test.rb (1)</summary><blockquote>

`55-68`: **Consider tightening the thumbnail selector if it becomes flaky.**

The CSS selector `.blog-post img, .post-image img, article img` is broad. If the blog listing markup changes, this test may need adjustment. The current approach is pragmatic for initial coverage.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@test/unit/cdn_image_proxy_test.rb` around lines 55 - 68, The selector used in
test_blog_thumbnails_use_cdn (".blog-post img, .post-image img, article img") is
too broad and may catch unrelated images; narrow it to target the actual listing
thumbnail elements (e.g. a more specific selector within the listing container
such as ".blog-listing .blog-post .thumbnail img" or a data-attribute like
"[data-role=\"thumbnail\"] img") so the test only inspects thumbnail images —
update the selector string in test_blog_thumbnails_use_cdn to a more specific
CSS path that matches your current listing markup (or add/target a stable data
attribute) and keep the same assertions for wsrv.nl, output=jpg and q=90.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @docs/workflows/cdn-image-proxy.md:

  • Around line 32-35: Add a language identifier (for example "text") to the
    fenced code block that contains the {{ partial "cdn/url" (dict "page" $page
    "resource" $resource "params" "w=400&output=webp&q=80") }} snippet and the
    arrowed example so markdownlint MD040 is resolved; update the opening fence from
    totext and keep the closing fence as ``` with no other content changes.

In @test/unit/cdn_image_proxy_test.rb:

  • Around line 55-68: The selector used in test_blog_thumbnails_use_cdn
    (".blog-post img, .post-image img, article img") is too broad and may catch
    unrelated images; narrow it to target the actual listing thumbnail elements
    (e.g. a more specific selector within the listing container such as
    ".blog-listing .blog-post .thumbnail img" or a data-attribute like
    "[data-role="thumbnail"] img") so the test only inspects thumbnail images —
    update the selector string in test_blog_thumbnails_use_cdn to a more specific
    CSS path that matches your current listing markup (or add/target a stable data
    attribute) and keep the same assertions for wsrv.nl, output=jpg and q=90.

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Path: .coderabbit.yaml

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `da5da7cc-2e94-4c09-8ce1-3cf29d2808f5`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 57bd0c2871efd52e7d95646af8fd92e8aa6357bf and b630be6aa502a7cef168f691aa55a4de19edf051.

</details>

<details>
<summary>📒 Files selected for processing (21)</summary>

* `.github/actions/setup-hugo/action.yml`
* `.github/workflows/_hugo.yml`
* `.github/workflows/test.yml`
* `bin/hugo-build`
* `config/_default/hugo.toml`
* `docs/workflows/cdn-image-proxy.md`
* `layouts/partials/seo/enhanced-meta-tags.html`
* `test/unit/cdn_image_proxy_test.rb`
* `themes/beaver/layouts/_markup/render-image.html`
* `themes/beaver/layouts/_shortcodes/img.html`
* `themes/beaver/layouts/partials/blog/img-cropped.html`
* `themes/beaver/layouts/partials/blog/json-ld.html`
* `themes/beaver/layouts/partials/cdn/url.html`
* `themes/beaver/layouts/partials/components/testimonial.html`
* `themes/beaver/layouts/partials/data/authors-cached.html`
* `themes/beaver/layouts/partials/data/company-cached.html`
* `themes/beaver/layouts/partials/data/testimonials-cached.html`
* `themes/beaver/layouts/partials/homepage/companies.html`
* `themes/beaver/layouts/partials/page/testimonials.html`
* `themes/beaver/layouts/partials/seo/enhanced-meta-tags.html`
* `themes/beaver/layouts/partials/technologies.html`

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (6)</summary>

* themes/beaver/layouts/_shortcodes/img.html
* config/_default/hugo.toml
* themes/beaver/layouts/partials/seo/enhanced-meta-tags.html
* themes/beaver/layouts/partials/blog/img-cropped.html
* .github/workflows/_hugo.yml
* layouts/partials/seo/enhanced-meta-tags.html

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

@pftg pftg force-pushed the feat/cdn-image-proxy branch 4 times, most recently from 8e76534 to 6cbfa91 Compare April 14, 2026 08:41
Build once, test with precompiled output:
- Hugo build in _hugo.yml uploads artifact, unit tests download it
- Unit tests moved from test.yml to publish.yml (needs: build)
- test.yml now only handles manual screenshot tests
- PRECOMPILED_ASSETS skips redundant Hugo rebuild in test helper

Hugo & actions upgrade:
- Hugo 0.149.1 → 0.160.1 (CI workflow + setup-hugo action)
- Migrate site.Data → hugo.Data (8 files, fixes deprecation warning)
- configure-pages v5→v6, upload/deploy-pages v4→v5
- FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 for peaceiris/actions-hugo v3

CDN cleanup from review:
- Extract shared partials/cdn/url.html (was 10+ copies)
- Fix trailing & in CDN URL when params empty
- Fix duplicate twitter:card meta tag
- Fix OG image fit=inside → fit=cover
- Remove SVG/mp4 from blog media cleanup
- Add preconnect hint for wsrv.nl
- bin/hugo-build: accept OUTPUT_DIR and BASE_URL env vars

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@pftg pftg force-pushed the feat/cdn-image-proxy branch from 6cbfa91 to 25b1f07 Compare April 14, 2026 08:44
@pftg pftg merged commit d643cc9 into master Apr 14, 2026
3 checks passed
@pftg pftg deleted the feat/cdn-image-proxy branch April 14, 2026 08:50
pftg added a commit that referenced this pull request Apr 14, 2026
The single.html cover image block was missed when CDN proxy support was
added in PR #285, causing 404s for all blog post cover images on
production (CI deletes processed images from public/blog/).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pftg added a commit that referenced this pull request Apr 14, 2026
The single.html cover image block was missed when CDN proxy support was
added in PR #285, causing 404s for all blog post cover images on
production (CI deletes processed images from public/blog/).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant