Images & Media — Formats, Uploads, and Optimization

Complete guide to images in Dax Pro: supported formats, optimal dimensions, uploading through Decap CMS, using external image URLs, alt text, lazy loading, and the pitfalls that break layouts or slow down pages.

Why Images Matter More Than You Think

Images are the single biggest contributor to page weight on most content sites. A site that renders in 50 milliseconds of HTML can become a 3-second page if the hero image is unoptimized. A gallery of 20 photos at 2 MB each becomes a 40 MB page load that visitors abandon before the first image appears.

Dax Pro is built to be fast. It ships zero JavaScript runtime, sub-second build times, and Lighthouse 100 by default. But it cannot compensate for images that are too large, wrong format, or incorrectly referenced. Image discipline is the difference between a site that stays fast as you add content and a site that gradually slows down with every post.

This chapter covers everything you need to know about images in Dax Pro:

1. Supported formats — what works and what does not

2. Optimal dimensions — the sizes that look sharp without bloating pages

3. Compression — how to reduce file size without losing quality

4. Uploading via Decap CMS — the visual workflow

5. Using external URLs — Unsplash, your own CDN, other sources

6. Alt text — the accessibility and SEO requirement

7. Lazy loading — how Dax Pro handles it automatically

8. Where images live — the public/images/ folder and its rules

9. Common mistakes — the patterns that break layouts or slow pages

By the end, you will know exactly how to add any image to any part of your site, at the right size, in the right format, with the right metadata.


Supported Formats

Dax Pro does not restrict image formats — any format the browser understands works. But four formats cover 99% of use cases, and each has a clear best use.

JPEG (.jpg, .jpeg)

Best for: photographs, complex images with many colors, gradients, anything with smooth transitions.

Why: JPEG compression is designed for photographic content. A 1200×630 photo saved as JPEG at 80% quality is typically 100–200 KB. The same photo saved as PNG would be 1–3 MB.

When to avoid: images with text or sharp edges. JPEG compression creates artifacts around text that make it look fuzzy.

PNG (.png)

Best for: screenshots, logos, icons, images with transparency, images with text and sharp edges.

Why: PNG is lossless — every pixel is preserved. Text stays crisp, sharp edges stay sharp, transparency works.

When to avoid: photographs. PNG files of photographs are 5–10 times larger than JPEG for the same visual quality.

WebP (.webp)

Best for: almost everything. WebP is the modern replacement for both JPEG and PNG.

Why: WebP achieves the same visual quality as JPEG at 25–35% smaller file size, and the same quality as PNG at 25–50% smaller. It supports transparency and animation. It is supported by every modern browser (Chrome, Firefox, Safari 14+, Edge).

When to avoid: when you need to support very old browsers (IE 11, Safari 13 and earlier). For most sites in 2026, WebP is the default choice.

SVG (.svg)

Best for: logos, icons, illustrations, anything that can be described as vector shapes.

Why: SVG is resolution-independent — it looks sharp at any size. It is also text-based, so it compresses extremely well and can be edited in a text editor.

When to avoid: photographs or any image with fine detail that cannot be represented as simple shapes.

The Decision Tree

Choose a format in this order:

1. Is it a logo, icon, or simple illustration? → SVG

2. Is it a screenshot, image with text, or needs transparency? → WebP (or PNG if WebP not possible)

3. Is it a photograph or complex image? → WebP (or JPEG if WebP not possible)

Dax Pro's default: WebP. The theme ships with WebP images for logos, hero images, and feature images. Use WebP unless you have a specific reason not to.


Optimal Dimensions

Every image in Dax Pro has a display size. The image should be provided at 1× or 2× the display size (never smaller, rarely larger).

Hero image

Display size: 640 × 360 pixels on desktop (large layout), 400 × 225 on mobile

Optimal file size: 1280 × 720 pixels

Why 2×: on high-density screens (Retina, 4K), the image is rendered at 2× the CSS pixel size. A 640-pixel-wide display needs a 1280-pixel-wide image to look sharp.

Format: WebP

Typical file size: 60–120 KB

OpenGraph / social image

Display size: 1200 × 630 pixels (standard for Twitter, Facebook, LinkedIn)

Optimal file size: 1200 × 630 pixels (exact match — this is the maximum most platforms display)

Format: JPEG (for photos) or WebP (for graphics)

Typical file size: 100–200 KB

The OpenGraph image is what appears when the page is shared on social media. It is configured in _data/metadata.yaml (image field) and can be overridden per post (image in the post frontmatter).

Post featured image

Display size: 400 × 225 pixels (listing card thumbnail) and 1200 × 675 pixels (post page cover)

Optimal file size: 1200 × 675 pixels

Format: WebP or JPEG

Typical file size: 80–150 KB

The featured image appears in two places: as a thumbnail on /posts/ and the homepage Insights section, and as a large cover at the top of the post page. Providing it at 1200 pixels wide works for both.

Homepage section images

Display size: 600–800 pixels wide, variable height

Optimal file size: 1200 × 675 pixels (or 800 × 450 for smaller cards)

Format: WebP or JPEG

Typical file size: 80–150 KB

Inline images in post body

Display size: up to 760 pixels wide (the prose content width)

Optimal file size: 1200–1500 pixels wide

Format: WebP or JPEG

Typical file size: 80–200 KB

Logo and favicon

Logo: SVG, any size (scales infinitely)

Favicon: 32 × 32 pixels (.ico) or 512 × 512 pixels (.png or .webp)

Favicons are often displayed at 16 × 16, 32 × 32, or 48 × 48 pixels depending on context. Providing a 512 × 512 source ensures the browser can downscale without loss.

A rule that scales

When in doubt: provide the image at 2× the largest display size.

  • A card that displays at 400 pixels → provide at 800 pixels
  • A hero that displays at 640 pixels → provide at 1280 pixels
  • A cover that displays at 1200 pixels → provide at 2400 pixels
  • The file size scales roughly linearly, so 2× dimensions typically produce 3–4× file size. That is acceptable — the quality gain on high-density screens is worth it.

    Never provide larger than 2×. A 4000-pixel image displayed at 400 pixels wastes 90% of the bandwidth. The browser downsamples but the file still downloads.


    Compression

    An uncompressed image is 3–10 times larger than a compressed one. Compression is the single highest-impact optimization.

    Tools

    TinyPNG (tinypng.com) — for PNG and JPEG. Free for images under 5 MB. Drag-and-drop. Reduces file size 60–80% with no visible quality loss.

    Squoosh (squoosh.app) — for any format. Google's image compression tool. Converts to WebP. Drag-and-drop, choose quality, download. The most versatile tool.

    ImageOptim — macOS app. Batch process a folder. Excellent for PNG and JPEG.

    Sharp — command-line tool. For developers. npm install -g sharp-cli, then sharp -i input.jpg -o output.webp --quality 80.

    cwebp — WebP-specific CLI. cwebp -q 80 input.jpg -o output.webp. Faster than Sharp for WebP only.

    Quality settings

    JPEG: 75–85. Below 75 produces visible artifacts. Above 85 produces large files with minimal gain.

    WebP: 75–85. WebP's quality scale is roughly equivalent to JPEG's — 80 WebP looks like 80 JPEG, but at half the file size.

    PNG: lossless by definition. Use pngquant or TinyPNG for lossy PNG (reduces colors), or convert to WebP.

    Target file sizes

    Image type Target size
    Hero image 100–150 KB
    OpenGraph image 150–250 KB
    Post featured image 100–200 KB
    Homepage section image 100–200 KB
    Inline image 100–300 KB
    Thumbnail 30–60 KB
    Logo (SVG) 5–20 KB
    Favicon 5–20 KB

    If any image is above its target, compress it. If it is above 500 KB, compress it again — that image is dominating the page weight.


    Uploading via Decap CMS

    The Decap CMS media library is the visual workflow for uploading images.

    Step 1: Open the media library

    When you are editing a post or a page with an image field, look for the image picker:

  • Image field — a button that says Choose an image or an image thumbnail
  • Click it
  • A media library opens
  • The media library shows all images currently in public/images/. If it is empty, no images have been uploaded yet.

    Step 2: Upload a new image

    1. Click Upload in the top-right of the media library

    2. Choose a file from your computer

    3. The image uploads to public/images/ with a name derived from its original filename

    4. The library shows the new image at the top

    5. Click the image to select it

    6. The image field updates with the path (/images/your-image.webp)

    Step 3: Adjust alt text (if the field supports it)

    Some image fields have a separate alt text field. If so, fill it in. If not, the post's title is used as a fallback alt text — not ideal but functional.

    Step 4: Publish

    Click Publish. The image path is saved to the frontmatter. On the next build, the image renders.

    File naming: Decap CMS preserves the uploaded filename. my-photo.jpg becomes /images/my-photo.jpg. Rename files before uploading to keep paths clean:

  • hero-dotnet-enterprise.webp ✓
  • IMG_20260512_143022.jpg ✗ (meaningless, hard to find later)
  • Overwriting: if you upload a file with the same name as an existing file, Decap CMS overwrites the existing one. This is usually fine, but be careful — if two posts share the same image path, overwriting the image updates both.

    Where uploaded files go

    Decap CMS writes uploads to the path configured in public/admin/config.yml:

    media_folder: "public/images"
    

    public_folder: "/images"

  • media_folder — the actual folder on disk
  • public_folder — the URL path used in frontmatter
  • Uploads go to public/images/. The path in frontmatter becomes /images/filename.webp. On build, public/images/ is copied to site/images/, and the URL /images/filename.webp resolves correctly.

    Do not change media_folder or public_folder unless you understand how the build pipeline copies files. Changing one without the other breaks all image links.


    Using External URLs

    You do not have to upload images to public/images/. You can reference any external URL.

    Unsplash (recommended for stock images)

    Unsplash (unsplash.com) provides free images for commercial use. Every image has a direct URL.

    To use an Unsplash image:

    1. Find an image on Unsplash

    2. Click Download or right-click the image and copy the image URL

    3. The raw URL looks like https://images.unsplash.com/photo-1451187580459-43490279c0fa

    4. Append query parameters to resize and optimize:

    ?w=1200&q=80&auto=format&fit=crop
    

  • w=1200 — width in pixels
  • q=80 — quality (80 is good for web)
  • auto=format — serve WebP when the browser supports it
  • fit=crop — crop to the requested aspect ratio
  • Full URL:

    https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1200&q=80&auto=format&fit=crop
    

    Paste into the image field. No upload. No local file. Unsplash's CDN serves the image at the requested size.

    Advantages:

  • No local file to manage
  • Automatically resized and compressed
  • Always available (Unsplash's CDN is reliable)
  • Free for commercial use
  • Disadvantages:

  • Depends on Unsplash's CDN (rare outages)
  • Cannot customize the image (crop, overlay) without re-hosting
  • Attribution recommended (not required, but courteous)
  • Other external URLs

    Any URL that serves an image works. Examples:

  • Your own CDN — https://cdn.example.com/images/hero.webp
  • Cloudinary — https://res.cloudinary.com/yourcloud/image/upload/w_1200/hero.jpg
  • GitHub raw — https://raw.githubusercontent.com/user/repo/main/image.jpg (not recommended — slow, not designed for production)
  • Imgur — https://i.imgur.com/abc123.jpg (not recommended for production)
  • For production sites, prefer either:

    1. public/images/ (uploaded via Decap CMS)

    2. A dedicated CDN (Cloudinary, Cloudflare Images, Bunny CDN)

    External image URLs from random free image hosts are unreliable. They may disappear, change their URL structure, or add rate limits. Self-host or use a paid CDN for images that appear on your site permanently.


    Alt Text

    Every element should have an alt attribute. Alt text serves two purposes:

    1. Accessibility — screen readers read alt text aloud to blind and low-vision users

    2. SEO — search engines use alt text to understand image content

    Dax Pro's default behavior:

  • Featured image (frontmatter image) — alt is the post title. This works but is not specific.
  • Inline images (alt text) — alt comes from the Markdown alt text.
  • Homepage section images — alt comes from the image_alt field in the frontmatter, or an empty string.
  • Writing good alt text:

  • Describe the image concretely. "A terminal showing the DAX build output" is better than "screenshot."
  • Do not repeat the surrounding text. If the paragraph already says "see the screenshot below," the alt text should describe what the screenshot shows, not that it is a screenshot.
  • Keep it short. Under 125 characters is ideal.
  • Do not start with "image of" or "picture of." Screen readers already know it is an image.
  • Use empty alt for decorative images. Decorative gradient divider with alt text describing a gradient is not helpful — an empty alt is better: .
  • Adding alt text in Markdown:

    A terminal showing the DAX build output: 49 pages in 127ms
    

    Adding alt text in frontmatter:

    image: "https://images.unsplash.com/photo-1234567890?w=1200&q=80&auto=format&fit=crop"
    

    image_alt: "A developer's desk with a laptop, notebook, and coffee"

    Alt text is required for featured images. Dax Pro's templates use the post title as a fallback, but a dedicated image_alt is better for SEO and accessibility. If the image field has an adjacent alt field, use it.


    Lazy Loading

    Dax Pro automatically applies loading="lazy" to images below the fold and fetchpriority="high" to the hero image (above the fold).

    What loading="lazy" does: the browser defers loading the image until it is about to enter the viewport. Images below the fold do not block the initial page render. The page becomes interactive faster.

    What fetchpriority="high" does: the browser loads the image with high priority, ensuring it appears as fast as possible.

    Where Dax Pro applies these:

  • Hero image (homepage) — fetchpriority="high", no lazy loading
  • Blog thumbnails — loading="lazy"
  • Homepage section images — loading="lazy"
  • Post cover — fetchpriority="high" (it is above the fold on the post page)
  • Inline images in Markdown — no automatic loading attribute (the Markdown renderer does not add it)
  • You do not need to configure lazy loading. It works automatically. If you edit a template and add an tag, add loading="lazy" yourself unless the image is above the fold.


    Where Images Live

    All local images live in public/images/. This folder is copied to site/images/ on every build. The public URL is /images/filename.ext.

    Structure:

    public/
    

    └── images/

    ├── dax-primary-logo.webp

    ├── hero-main.webp

    ├── og-default.jpg

    ├── favicon.ico

    └── posts/

    ├── why-static-sites-win.webp

    ├── blazor-vs-dax.webp

    └── decap-cms-guide.webp

    Subfolders are fine. Organize images by type, date, or topic:

  • images/posts/ — featured images for blog posts
  • images/services/ — featured images for services
  • images/homepage/ — homepage section images
  • images/og/ — OpenGraph images
  • The URL includes the subfolder: /images/posts/why-static-sites-win.webp.

    Do not use spaces in filenames. /images/my image.webp breaks in URLs. Use hyphens: /images/my-image.webp.

    Do not use uppercase in filenames. /images/Hero.WebP is case-sensitive on Linux servers but not Windows. Use lowercase: /images/hero.webp.

    Do not put images outside public/. Files outside public/ are not copied to site/. If you put an image in images/ (root) instead of public/images/, it does not appear on the built site.


    Common Image Mistakes

    Mistake 1: Providing images at original resolution.

    A 4000×3000 photo from a phone camera is 4–8 MB. Displayed at 640×360, it wastes 95% of the bandwidth. Resize before uploading.

    Mistake 2: Using PNG for photographs.

    A photograph saved as PNG is 5–10× larger than the same photograph as JPEG. Screenshots and graphics are fine as PNG; photographs should be JPEG or WebP.

    Mistake 3: Not compressing.

    An uncompressed 1280×720 WebP is 500 KB. Compressed at quality 80, it is 80 KB. The visual difference is invisible; the file size difference is 6×.

    Mistake 4: Spaces or uppercase in filenames.

    /images/My Image.webp breaks. Use /images/my-image.webp.

    Mistake 5: Missing alt text.

    Featured images have a fallback (post title), but inline images with empty alt text fail accessibility audits. Always provide alt text for content images.

    Mistake 6: Hotlinking from unreliable sources.

    https://example.com/some-image.jpg may disappear tomorrow. Upload important images to public/images/ or a CDN you control.

    Mistake 7: Images outside public/.

    A file at images/hero.webp (root level) is not copied to site/. Only public/ contents are copied. Put images in public/images/.

    Mistake 8: Forgetting image_alt in frontmatter.

    The image_alt field in the frontmatter is used for the featured image's alt text. Without it, the post title is used — which is not always descriptive.

    Mistake 9: Using an inline image URL that returns HTML, not an image.

    Some URLs (like Google Image search results) are HTML pages, not image files. https://example.com/photo may return an HTML page. Use the direct image URL, usually ending in .jpg, .png, .webp, or .svg.

    Mistake 10: Not testing the image on mobile.

    An image that looks great on a 1920-pixel desktop may be too small on a phone at 2× density. Always check the mobile view (resize the browser or use DevTools' device emulation).

    Mistake 11: Favicon is too large or wrong format.

    A 5000×5000 favicon is 50 KB that the browser downloads on every page. Favicons should be 32×32 or 512×512. Use .ico (universal) or .png. WebP favicons work in modern browsers but not all.

    Mistake 12: Using the same image for everything.

    A single hero image reused on every page is not a bug, but it is a missed opportunity for visual variety. Each page benefits from a specific image.


    Verifying Images Work

    After adding an image:

    1. Rebuild — dotnet run -- build

    2. Open the page — navigate to the page in a browser

    3. Confirm the image renders — no broken icon, no blank space

    4. Check the file size — open DevTools' Network tab, find the image request, confirm it is under 300 KB

    5. Check the URL — the image request URL is /images/..., not a 404

    6. Check mobile — resize the browser to 375 pixels wide, confirm the image scales correctly

    7. Check alt text — view source, find the tag, confirm alt is populated

    8. Check lazy loading — for below-fold images, confirm loading="lazy" is in the source

    If the image does not render:

  • Path is wrong — /images/filename.webp must match the actual file at public/images/filename.webp
  • File is not in public/ — files outside public/ are not copied
  • Filename has spaces or uppercase — rename to lowercase with hyphens
  • Build has not run — rebuild after adding the image
  • External URL is broken — open the URL directly in a browser; if it 404s, the URL is wrong
  • If the image renders but the page is slow:

  • File size is too large — compress with Squoosh or TinyPNG
  • Too many large images on one page — split into multiple pages or reduce per-page count
  • Lazy loading is missing — check the template; Dax Pro adds it by default but custom templates may not

  • What You Have Now

    After this chapter, you can:

  • ✅ Choose the right image format for any use case
  • ✅ Size images correctly (2× display size)
  • ✅ Compress images to target file sizes
  • ✅ Upload images via Decap CMS
  • ✅ Use external image URLs (Unsplash, CDNs)
  • ✅ Write meaningful alt text
  • ✅ Understand lazy loading and where it applies
  • ✅ Organize images in public/images/
  • ✅ Verify images render correctly at the right size
  • ✅ Fix the twelve most common image mistakes
Images are the visual layer of your site. When they are fast, sized correctly, and described well, the site feels professional. When they are slow, oversized, or missing alt text, the site feels broken — even if everything else is perfect.

The next chapter is SEO — how Dax Pro generates sitemaps, robots.txt, OpenGraph tags, and JSON-LD structured data automatically, and what you need to do to make search engines and social platforms index your site correctly.