An open-source template for a film photography portfolio: publish your rolls, add metadata (camera, film, locations), and showcase highlights. All content lives in your own GitHub repository.
New to GitHub or the command line? See the simplified setup guide for step-by-step help with no coding.
| Landing page | Roll page | Archive & filter |
|---|---|---|
![]() |
![]() |
![]() |
| Search and filter | Adding a roll in the CMS |
|---|---|
![]() |
![]() |
- Roll-by-roll publishing with metadata (camera, film, lenses, dates, locations)
- Web-based admin (Decap CMS) so you can add and edit rolls in the browser—no need to edit files by hand
- Search and filters by camera, film, location, date, etc.
- Lightbox viewer with touch support and full-screen
- Light and dark themes, accessible (WCAG 2.2 when you add alt text to images)
- Optional: visitor comments, batch import from folders of photos
- Option A: On GitHub, click Use this template → Create a new repository, then clone it to your computer (or use GitHub Codespaces).
- Option B: Follow the simplified setup guide if you prefer a guided flow.
Open global.config.yml in the project root and set:
- Site name and base URL (your site’s public URL, e.g.
https://myfilm.netlify.app) - Author name and default title for the site
- Any other options described in the file
Save the file.
So the admin suggests your gear when you add a roll:
- In
global.config.yml, add your cameras, films, and lenses under the sections shown there. - In a terminal, from the project folder, run:
yarn setup(ornpm run setup).
- Go to netlify.com and sign in (or create an account).
- Click Add new site → Import an existing project and connect your GitHub account.
- Select the repository you created. Netlify will suggest:
- Build command:
yarn build(ornpm run build) - Publish directory:
dist
- Build command:
- Click Deploy site and wait for the first build to finish.
- In Netlify: Site configuration → Identity → Enable Identity.
- Under Registration, set it to Invite only (recommended).
- Open Identity → Invitations and Invite yourself (use the email you want to use for the CMS).
- Accept the invite from the email and set a password.
- Go to Site configuration → Identity → Services and enable Git Gateway (so the CMS can save changes to GitHub).
- In Netlify: Site configuration → Environment variables → Add a variable (or Import from .env).
- Add:
GITHUB_REPO_OWNER= your GitHub username (or organization name)GITHUB_REPO_NAME= the name of this repository (e.g.film-photography-archive)GITHUB_TOKEN= a GitHub Personal Access Token with repo (or at least contents: read). Needed for image previews and to avoid rate limits.
- Save and trigger a new deploy (Deploys → Trigger deploy) so the new variables are used.
- Your site:
https://<your-site-name>.netlify.app - Admin (add and edit rolls):
https://<your-site-name>.netlify.app/admin
Log in with the Identity account you invited, then you can create rolls, upload photos, and publish.
- Easiest: open
/adminon your site, log in, and use New Film roll. - You can also add a new file in
src/content/rolls(see existing rolls for the format).
Rolls are numbered per calendar month. For example: in October you use 1, 2, 3…; in November you start from 1 again. The site uses a slug like year–month–roll number–title (e.g. 2018-5-1-italy).
- Edit
global.config.ymland add the new camera, film, or lens in the right section. - Run
yarn setup(ornpm run setup). The CMS will then offer them when you edit a roll.
Highlights (featured collections) are in src/content/features. You can create them in the CMS or by adding markdown files. To link a photo in a roll to a feature, set the Feature field on that image to the feature name (e.g. “Scotland”).
To generate many rolls from folders of photos, use the generateRollContent.js script. Folders should be named like YYYYMM-<roll-number> (e.g. 201805-1). Run:
node generateRollContent.js /path/to/your/photo/foldersImages don’t show in the admin preview
Make sure GITHUB_REPO_OWNER, GITHUB_REPO_NAME, and GITHUB_TOKEN are set in Netlify (see step 6 above), then trigger a new deploy.
Newly uploaded image doesn’t appear in the preview
New photos should usually show in the preview, but it may not always work. If you don’t see the image, try Publish (to save it to the repo) and reload the preview.
Build on Netlify times out
The first build can be slow with many images. You can build locally and deploy with npx netlify deploy --prod, or temporarily remove some rolls, deploy, then add them back.
Visitor comments
Set enable_comments: "on" in global.config.yml and add a GITHUB_TOKEN with write access in Netlify. Comments are submitted as pull requests; you approve them in GitHub.
Translations
UI text is in the i18n folder. You can add another language by following the existing structure.
Use this if you want to run the site and admin on your computer.
- Clone the repo and run
yarn install(ornpm install). - Edit
global.config.yml(and runyarn setupif you changed cameras/films/lenses). - Build the admin UI once:
cd admin-app && npm install, then from the project rootnpm run build:admin. - Run the site:
yarn dev(ornpm run dev). Open http://localhost:4321 (or the port shown). - Admin at http://localhost:4321/admin
- For published images to show in the preview, run
netlify devinstead ofyarn dev, and add a.env(copy from.env.example) withGITHUB_REPO_OWNER,GITHUB_REPO_NAME, andGITHUB_TOKEN. - For draft uploads to show in the preview, run
npx decap-serverin a second terminal.
- For published images to show in the preview, run
The main yarn build (or npm run build) builds both the admin and the site; use it before deploying or to test the production build with npx astro preview.
This project is licensed under the MIT License. See the LICENSE file for details.
Photos in src/assets/images/images are by Tommy Feldt and are under CC0 1.0.
- Hasselblad icon from The Noun Project by Assiya Dauyek (CC BY 3.0).
- PhotoSwipe (MIT) for the gallery.




