Getting Started with the Template
Welcome! This guide walks you through everything you need to turn this template into your own photography site — from installation to your first published post. Most of your day-to-day work happens in plain Markdown and one config file, so you can stay focused on the images.
What this template is built on
- Astro 7 — a fast, component-based, static-first framework.
- Sass for styling, with CSS variables driving theme + dark mode.
- GSAP, Lenis, Splitting, Swiper, Paper.js — the motion, smooth-scroll, and interaction layer.
- astro:assets / Sharp — automatic image optimization for photos imported from
src/.
You don’t need to be an expert in any of these to customize the site — the sections below point you to the exact files to edit.
1. Requirements & installation
The project requires Node.js 22.12 or newer. Check with node -v, then install dependencies and start the dev server:
npm install
npm run dev # starts the dev server (with --host, so you can preview on your phone)
Useful scripts:
| Command | What it does |
|---|---|
npm run dev |
Local dev server with live reload |
npm run build |
Builds the production site to dist/ |
npm run preview |
Previews the production build locally |
npm run check |
Type-checks .astro / .ts files |
Prefer
pnpmoryarn? Swap the commands — the project works with any of them.
2. Project structure
tink-photography-sale-template/
├── public/ # Static files served as-is
│ ├── hero01.jpg # Homepage main hero image
│ ├── hero02.jpg # Homepage side image
│ ├── og.jpg # Social share preview
│ ├── favicon.svg
│ └── menu/ # Collection cover thumbnails (home page menu)
├── src/
│ ├── assets/images/ # Images optimized via astro:assets
│ │ ├── about.jpg
│ │ ├── tink.jpg # Author avatar
│ │ └── sunset/, city/, nature/, moment/, altay/
│ ├── components/ # UI building blocks (Header, Footer, Gallery…)
│ │ └── elements/ # Small reusable elements (alias: @/elements)
│ ├── config/
│ │ └── site.ts # ← Start here: all site-wide settings
│ ├── content/
│ │ └── blog/ # Blog posts as Markdown (.md)
│ ├── data/
│ │ └── gallery/ # Collection / photo data (sunset, city, …)
│ ├── layouts/ # Page layouts
│ ├── pages/ # File-based routes (each file = a URL)
│ │ ├── index.astro # Home
│ │ ├── about.astro
│ │ ├── blog.astro # Journal listing
│ │ ├── blog/[...slug].astro
│ │ └── collection/ # Collection pages
│ └── content.config.ts # Blog collection schema (frontmatter rules)
├── astro.config.mjs # Astro config + path aliases
├── tsconfig.json
└── package.json
Two path aliases are configured for cleaner imports (see tsconfig.json / astro.config.mjs):
@/→src/@/elements/→src/components/elements/
3. Configure your site
Almost everything brand-related lives in one file: src/config/site.ts. Open it and edit the values in siteConfig:
export const siteConfig = {
name: "Tink Photo Gallery", // site name
shortName: "Tink.", // compact logo text
tagline: "Visual stories", // used around the site
url: "https://example.com", // ← set this to your real domain
locale: "en-US",
seo: {
title: "Tink Photo Gallery",
description: "A quiet collection of visual stories…",
keywords: "Tink, photography, photo gallery, portfolio",
},
author: {
name: "Tink",
role: "Photographer",
bio: "An independent photographer collecting quiet observations…",
email: "tink@example.com", // shown in the footer/contact area
avatar: authorAvatar,
profile: [ /* the rows on the About page — see §7 */ ],
},
socials: [], // add your social links here
analytics: { google: "", baidu: "" },
};
Further down the same file you’ll find:
navigationItems— the links in the site header/menu.categoryItems— the collection cards on the home page (label, link, photo count, cover image).categoryById— a lookup map generated fromcategoryItems.
Change the text here and it updates across the whole site. Set siteConfig.url to your production domain — it’s used for SEO and absolute links.
4. The homepage
The hero on the home page is defined directly in src/pages/index.astro. To make it yours:
- Headline & intro — edit the
hero-splitting-titletext and thehero-textparagraph. - Hero images — replace
public/hero01.jpgandpublic/hero02.jpgwith your own (keep the same filenames, or update the<img src>paths).
The hand-drawn underline beneath the headline is an inline SVG — feel free to leave it, hide it, or redraw it.
5. Collections & galleries
Each collection (Sunset, City, Nature, Moments, Altay) is described by a data file in src/data/gallery/, e.g. sunset.ts. Photos are imported individually so they get optimized:
import img000 from '../../assets/images/sunset/000.jpg';
export const sunsetGallery: GalleryConfig = {
id: 'sunset',
slug: 'sunset',
title: 'Sunset',
description: 'A study of warm horizons and the last light by the water.',
featured: true,
images: [
{
src: img000,
alt: 'Sunset at the beach',
layout: { cols: { default: '12', sm: '10' }, align: 'center' },
},
// add more images…
],
};
To add photos to a collection:
- Drop the files into
src/assets/images/<collection>/(e.g.src/assets/images/sunset/). - Import them at the top of the matching gallery file and add an entry to the
imagesarray.
The layout system uses a 12-column grid:
cols— how wide the image is at each breakpoint (default,sm,md,lg).offset— pushes the image right by N columns.align— vertical alignment (start|center|end).
Mix these to create the magazine-style rhythm the template is known for.
To register a gallery, make sure it’s imported and listed in the allGalleries array in src/data/gallery/index.ts.
The home-page menu is separate: each card comes from categoryItems in site.ts, and its cover image is read from public/menu/ (e.g. public/menu/sunset.jpg).
6. Write a blog post
Blog posts are Markdown files in src/content/blog/. The filename becomes the URL — for example getting-started.md lives at /blog/getting-started. To create a new post, add a .md file with this frontmatter:
---
title: My New Post
description: A short summary shown in the journal list.
publishDate: 2026-08-06
read: 5
tags:
- Notes
---
Write your post in **Markdown**. Code blocks, images, blockquotes,
and tables are all supported.
The frontmatter schema (defined in src/content.config.ts):
| Field | Type | Required | Notes |
|---|---|---|---|
title |
string | yes | Shown as the post heading |
publishDate |
date | yes | YYYY-MM-DD; newest posts list first |
description |
string | no | Summary in the journal list + SEO |
read |
number | no | Estimated read time in minutes |
tags |
string[] | no | First tag shows as the pill above title |
img/img_alt |
string | no | Optional cover image |
Posts are listed automatically on /blog (the Journal), sorted by publishDate — newest first.
7. The About page
The About page is data-driven — its content comes from author.profile in site.ts. Each entry is a label/value row, and any row with an href becomes a clickable link:
profile: [
{ id: "name", label: "Name", value: "Tink" },
{ id: "role", label: "Practice", value: "Photography" },
{ id: "focus", label: "Focus", value: "Light, landscape, and the moments between." },
{ id: "email", label: "Email", value: authorEmail, href: `mailto:${authorEmail}` },
{ id: "blog", label: "Journal", value: "Field notes & stories", href: "/blog" },
{ id: "bio", label: "About", value: "An independent photographer drawn to quiet intersections…" },
],
Add, remove, or reorder rows to shape the page — no template editing required.
8. Images & assets
Two places for images, used differently:
public/— files served exactly as-is. Use for hero images, OG previews, favicons, and collection menu covers. Reference them by absolute path:/hero01.jpg.src/assets/images/— images imported in code. These run through astro:assets/Sharp for optimization and responsive sizing. Use this for gallery photos and any image you want compressed.
As a rule: gallery photos → src/assets/images/; decorative/site-wide imagery → public/.
9. Theme & dark mode
Colors are defined as CSS variables (look for --color-* and --gallery-bg tokens in component styles). The site supports light and dark modes via a .dark class on the root, toggled by the theme button. To rebrand, adjust these variables — most of the palette flows from a handful of tokens.
Styles are written in Sass (<style lang="scss"> inside .astro files), so you can use nesting and variables right where the markup lives.
10. Build & deploy
When you’re ready to publish:
npm run build # outputs a static site to dist/
npm run preview # optional: sanity-check the build locally
The output in dist/ is fully static, so it deploys anywhere:
- Netlify / Vercel / Cloudflare Pages — point them at the repo; build command
npm run build, publish directorydist. - GitHub Pages — deploy the
dist/folder via your preferred action.
Before deploying, set siteConfig.url in site.ts to your real domain so canonical URLs, the OG image, and sitemap resolve correctly.
That’s the whole workflow: edit site.ts for text and brand, drop photos into src/assets/images/ and wire them up in a gallery file, and write Markdown in src/content/blog/. Everything else — layout, animation, optimization — is handled for you.
Happy shooting, and thanks for choosing the template.




