Appearance
Image storages
This document outlines the standard practices for image management within our project.
For image format guidelines, optimization recommendations, and workflow with designers, see Image Guidelines for Designers.
Image storages
There are two main storages:
- This git repository,
resources/imgdirectory (processed byVite::asset()). For:- UI elements (icons, logos, backgrounds)
- Default images (stubs)
- Any small images that are part of the application's core design
- AWS S3
ixdf--imagesbucket (s3-imagesfilesystem disk). For:- User-uploaded content (profile pictures, images for entities stored in Database (example: courses))
- High-resolution images (to avoid git repo bloat)
- Large images (>1Mb) (to avoid git repo bloat)
- Cache for generated images (e.g., certificates)
- Images that change frequently (to avoid git repo bloat)
- Images used in emails and other notifications (persistent URLs)
While using this repository is easier for the development process, we should avoid storing large images here to prevent the repository from becoming bloated.
Store Decision Matrix
| Scenario | Storage Option |
|---|---|
| Small, static UI elements | Git Repository |
| Large images (>1MB) | AWS S3 (ixdf--images) |
| User-uploaded content | AWS S3 (ixdf--images) |
| Frequently changing images | AWS S3 (ixdf--images) |
| Images needed in emails with persistent URLs | AWS S3 (ixdf--images) |
| Part of application's core design | Git Repository |
| Downloadable images, docs and archives | AWS S3 (ixdf--assets) |
CDN
Both stores are connected to CDNs (CloudFront) to ensure optimal performance:
assets.interaction-design.orgdomain Vite assets (stored in GitHub repo and then distributed via our CDN (E1UQEIYQ3OG2MMDistribution ID))public-images.interaction-design.orgfors3-imagesdisk (ixdf--imagesbucket)
You don't need to add the domain to the URL, these functions will do it for you:
Vite::asset()for Vite assets. Example:Vite::asset('resources/img/pictograms/member-placeholder.svg')public_img_url()fors3-imagesdisk. Example:public_img_url($member->picture_pic_url)
Vite
Vite::asset('resources/img/pictograms/member-placeholder.svg') output examples from different envs:
Production URLs are served by CloudFront CDN, because of the ASSET_URL .env variable.
Hash part of the URL (-CvAHbb8S) is generated based on the file content (checksum) and thus changed only when the file content is changed.
Vite::asset vs. @vite
Please don't confuse Vite::asset() calls with @vite('resources/pcss/pages/uxArticle.css') Blade directive. The first one generates a URL for an asset file, while the second one generates <link> or <script> tag with an URL inside (it does even more, like resource prefetch tags, but it's out of the topic of this doc).
Other storages
There are some other places where we store images:
- Other deprecated S3 buckets (mostly
idf--assetsthat is linked to thepublic-media.interaction-design.orgdomain ands3disk, also connected to the ImageKit). - CSS using
url('data:image.... Rarely used, please avoid using it. - HTML using
<img src="data:image...">, usually to inject SVG. Rarely used, please avoid using it.
Legacy note
There is one legacy trick we use for historical reasons on nginx level: redirect all /images/* requests to the public-media.interaction-design.org domain:
shell
# Redirecting assets to the CloudFront distribution (CDN)
rewrite ^/(images)/(.*)$ https://public-media.interaction-design.org/$1/$2 redirect;This allows not specifying domain for such URLs in the codebase, but is considered a bad practice and should be avoided in new code.