How the HowToCook Repository Handles Image Assets: Co-Location and Static Site Generation
The HowToCook project handles image assets by co-locating them with Markdown recipe files and leveraging the MkDocs same-dir plugin to treat non-Markdown files as static assets that are copied directly to the output site.
The Anduin2017/HowToCook repository is an open-source cookbook that manages thousands of recipe images alongside its Markdown documentation. Understanding how this project handles image assets reveals an elegant approach to static site generation that keeps content and visuals tightly coupled while maintaining a simple, portable file structure.
Co-Locating Images with Markdown Documentation
Rather than using a centralized assets folder, the HowToCook repository stores image files directly alongside the Markdown documents that reference them. Each recipe resides in its own directory within the dishes/ hierarchy, containing both the instructional text and the corresponding visual assets.
For example, the recipe for 鸡蛋羹 (steamed egg custard) lives at dishes/vegetable_dish/鸡蛋羹/. This directory contains the 鸡蛋羹.md file plus the associated image files such as 鸡蛋羹.jpg. This co-location strategy ensures that moving or deleting a recipe automatically moves or deletes its associated media, preventing broken references and orphaned assets.
Referencing Image Assets with Relative Paths
The project uses standard Markdown image syntax with relative paths to link to co-located assets. Because images reside in the same directory as the Markdown file, the reference uses a simple ./ prefix followed by the filename.
In dishes/vegetable_dish/鸡蛋羹/鸡蛋羹.md, the reference appears as:

This relative path approach ensures that the documentation remains portable and renders correctly both in GitHub's native Markdown viewer and in the generated static site. The ./ explicitly indicates the current directory, making the asset relationship unambiguous regardless of the build environment.
Static Site Generation with MkDocs
The HowToCook project uses MkDocs to transform the Markdown repository into a published website. While MkDocs traditionally expects static assets to reside in a dedicated docs/ directory or configured extra paths, this project employs a specific plugin to handle the distributed asset model.
Configuring the same-dir Plugin
The MkDocs configuration template at .github/templates/mkdocs_template.yml explicitly enables the same-dir plugin to support the co-located asset strategy:
plugins:
- same-dir
- search
The same-dir plugin instructs MkDocs to treat any non-Markdown file found in the same directory as a Markdown document as a static asset. This eliminates the need to manually configure extra_css or extra_javascript paths for each recipe's images, allowing the build system to automatically discover and copy assets based on their physical location in the file tree.
How Static Assets Are Processed
During the build process, MkDocs traverses the repository structure. When it encounters the 鸡蛋羹.jpg file in dishes/vegetable_dish/鸡蛋羹/, the same-dir plugin flags it as a static asset. MkDocs then copies this file to the corresponding location in the site/ output directory without processing its contents.
This approach preserves the original filenames and directory hierarchy in the generated site, ensuring that the relative links in the Markdown (./鸡蛋羹.jpg) resolve correctly in the final HTML. The result is a static site where each recipe page displays its associated images without requiring complex asset pipelines or CDN configurations.
Automated README Generation
The repository includes a Node.js script at .github/readme-generate.js that automatically updates the main README and navigation structures. This script scans the dishes/ directory to build tables of contents and MkDocs navigation, but it deliberately does not manipulate image files.
The script constructs Markdown links using a simple template function:
function inlineReadmeTemplate(file, path) {
return `- [${file.replace('.md', '')}](${path}/${file})\n`;
}
By focusing solely on Markdown file paths and leaving image handling to MkDocs and the same-dir plugin, the automation maintains a clean separation of concerns. Images remain ordinary files in the filesystem, managed by Git version control and served by the static site generator without requiring custom build logic.
Summary
- Co-location strategy: Image assets reside in the same directories as their corresponding Markdown recipe files, such as
dishes/vegetable_dish/鸡蛋羹/鸡蛋羹.jpgalongside鸡蛋羹.md. - Relative referencing: Recipes use standard Markdown syntax with relative paths (
) to ensure portability across GitHub and generated sites. - MkDocs same-dir plugin: The
.github/templates/mkdocs_template.ymlconfiguration enables thesame-dirplugin, which automatically treats co-located non-Markdown files as static assets during the build process. - Automation separation: The
.github/readme-generate.jsscript manages navigation and README updates without processing image files, delegating asset handling entirely to the static site generator.
Frequently Asked Questions
Where are image assets stored in the HowToCook repository?
Image assets are stored directly alongside the Markdown recipe files that reference them. Each recipe folder within the dishes/ directory contains both the .md documentation and the associated image files (.jpg, .jpeg, .png). For example, the steamed egg custard recipe at dishes/vegetable_dish/鸡蛋羹/ contains both 鸡蛋羹.md and 鸡蛋羹.jpg.
What MkDocs plugin handles static image assets?
The same-dir plugin handles static image assets in the HowToCook project. Configured in .github/templates/mkdocs_template.yml, this plugin instructs MkDocs to treat any non-Markdown file found in the same directory as a Markdown document as a static asset. It automatically copies these files to the output site without processing their contents, preserving the original filenames and directory structure.
Does the README generation script process image files?
No, the .github/readme-generate.js script does not process or manipulate image files. The script only scans the repository to extract Markdown file paths and build navigation tables for the README and MkDocs configuration. It delegates all image asset handling to the MkDocs build process and the same-dir plugin, maintaining a strict separation between navigation automation and static asset management.
How do you reference an image in a recipe Markdown file?
To reference an image in a HowToCook recipe file, use standard Markdown image syntax with a relative path pointing to the co-located image file. Because the image resides in the same directory as the Markdown file, the reference uses the ./ prefix followed by the filename. For example: . This relative path ensures the image displays correctly both on GitHub and in the generated MkDocs site.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →