Collections (Services, Team, Journal & More)
Collections
Skill level: Beginner · Files: src/content/<collection>/<language>/, defined in src/content.config.ts
A collection is a folder of similar entries: services, team members, journal posts, authors. Most entries are one file and one page. The list page of the collection (for example /services/) takes its title and section blocks from the -index.md file in the same folder (-index.mdx for the journal). Files whose name starts with _ are ignored, so _draft-post.md never becomes a page.
Projects and photo series have their own page: see Projects.
Add An Entry
- Copy an existing entry in the folder, for example
src/content/services/english/packaging.md. - Rename the copy. The file name becomes the URL (
/services/signage/), unless you setcustomSlug. - Change the frontmatter values and the Markdown body. Keep the keys.
- Add the same file name in
french/andarabic/with the translated text.
To hide an entry, set draft: true. It still shows in npm run dev, but it is left out of the built site, the lists, the sitemap, and search. draft: true in a folder’s -index.md hides the list page and every entry in that folder.
Collection Reference
The fields every page accepts (title, description, image, draft, customSlug, SEO fields) work on every entry. The table lists the extra fields. Each entry file shows its fields with comments.
| Collection | Folder | URL | Extra fields |
|---|---|---|---|
| Services | services/ | /services/<file>/ | icon, imageAlt, category, weight, price, duration, deliverables, tools, process, related, faq, detail |
| Team | team/ | /team/<file>/ | profession, location, email, phone, social, weight |
| Journal posts | blog/ | /blog/<file>/ | date, updated, author, categories, tags, featured, imageDark |
| Authors | author/ | (shown on posts) | title (the name), role, image, description, links |
| Projects | projects/ | /projects/<file>/ | See Projects |
These folders hold only a -index.md file, the content of one page: about-us/ (/about/), testimonials/ (/testimonials/), pricing/ (/pricing/), faq/ (/faq/), and contact/ (/contact/).
Services
Each service file is one service page, and the services sections on the homepages and /services/ list them in weight order (lowest first).
title: "Brand identity"description: "A mark, a type system, and a colour palette..."image: "/images/services/brand-identity.jpg"imageAlt: "Two blank business cards on a dark wooden surface"icon: "PenTool" # a Lucide icon name, or a local SVG pathweight: 1price: from: "€9,200" # the final text; it counts up unit: "per project"duration: "6–8 weeks"deliverables: - "Logo and wordmark" - "Brand guidelines (PDF)"tools: ["Research", "Sketching", "Typography"] # names from tools-section.mdprocess: - title: "Brief" description: "A half-day conversation..." duration: "Week 1"related: ["ceramic-forms", "envelope-system"] # project idsfaq: - question: "Do you also name businesses?" answer: "Yes, when the brief needs it..."The service page shows, in order: the page header with the starting price and duration, the cover, the Markdown body, the deliverables and tools, the process steps, the related projects, the faq, and the call to action. A part with an empty list is left out.
iconis a Lucide name, such asPenTool, or the path of a local SVG. It shows on the service cards and rows.toolstakes thenameof items insrc/content/sections/<language>/tools-section.md. Each one shows with that item’s icon, so spell the names the same way.categoryis a group name for your own use. No demo page shows it.- Write prices as they should read in each language:
"€9,200"in English,"9 200 €"in French.
The detail block. The headings and short lines around each list on a service page are written once, in detail in src/content/services/<language>/-index.md: buttons (under the page header line), deliverables, tools, process, related (with its button), and faq. A service file can add its own detail: block to change any part for that page only. Objects merge key by key, and lists replace the whole list. A button in detail.buttons with an empty url links to your booking page ([settings.contactInfo] booking).
Team
/team/ shows every member as a card, in weight order. Each member has a page at /team/<file name>/ with the portrait, the bio (the Markdown body), the contact rows, and a strip of the other members.
title: "Elio Brask"description: "Leads design at the studio..." # the line under the name, and the meta descriptionimage: "/images/people/team-design-lead.jpg" # portrait, 4:5profession: "Design lead"location: "Rotterdam"weight: 1social: - enable: true label: "Instagram" icon: "/images/icons/social/instagram.svg" # an SVG drawn in the text color, or a Lucide name url: "https://www.instagram.com/"The team grid is src/content/sections/<language>/team-grid-section.md. Its options are layout (grid or strip), items (member ids in order; empty lists everyone), limit, and columns (3 or 4 on large screens). A member file can change the strip on its own page with a teamGridSection: block.
Testimonials
Testimonials are not separate files. The quotes are the items list of src/content/sections/<language>/testimonials-section.md, and the same list shows on /testimonials/, the about page, and the homepages.
items: - quote: "Hugo spent a morning in the kiln room before he drew anything..." emphasis: "The labels read like our glaze notebook" # a phrase copied exactly from `quote`, set in a heavier weight name: "Joel Ashcombe" role: "Founder" company: "Marrow Kiln" image: "/images/people/client-1.jpg" # a square portrait, or "" for the name only rating: "5.0" # shown with one star; "" hides itproof is the rating row in the heading (rating, label, and up to 3 portraits). src/content/testimonials/<language>/-index.md holds the page header and the blocks of /testimonials/.
Journal
The journal is the blog collection, at /blog/. Posts can be .md or .mdx; use .mdx for shortcodes.
title: "How I price a project, and why I stopped counting hours"description: "Fixed prices with a written scope..."image: "/images/blog/desk-paper.jpg"date: 2026-08-18author: "Hugo Merrin"categories: - Businesstags: - "pricing"- Featured post.
featured: trueputs the post in the large card at the top of/blog/. Without it, the newest post is featured. - Categories and tags get their own list pages,
/blog/category/<name>/and/blog/tag/<name>/. The category chips above the posts come fromfilter.categoriesinsrc/content/sections/<language>/blog-list-section.md, in that order; categories missing there are added at the end. updatedshows an “Updated” date on the post.imageDarkis an optional cover for dark mode.- Automatic parts: reading time, the table of contents, related posts (posts that share a category first), the tags, the Copy page menu, the author box, and the RSS feed at
/blog/rss.xml. - Posts per page:
blogPaginationinconfig.toml(6). The featured card takes the place of two cards on the first page. - The journal page also shows the newsletter section. See Forms.
On the homepages, the journal section picks posts with options.featured (the post id of the large card), options.items, and options.limit.
Authors
A post’s author: "Hugo Merrin" is matched to src/content/author/english/hugo-merrin.md: the name in lowercase, with dashes. The author box at the end of the post shows when that file exists and has a description.
title: "Hugo Merrin"role: "Independent brand designer and art director"image: "/images/people/persona-designer.jpg" # optionaldescription: "Hugo designs identities, packaging, and print..."links: - label: "Instagram" url: "https://www.instagram.com/"About Page
src/content/about-us/<language>/-index.md holds the page header and the blocks of /about/: aboutSection, statsSection, servicesSection, testimonialsSection, logosSection, and ctaSection. The portrait, name, paragraphs, and social links are in src/content/sections/<language>/about-section.md, and the work history rows in experience-section.md.
Do It With AI
Add a [service | team member | journal post | author] to src/content/[services | team | blog |author]/english/ for: [DETAILS]. Copy the frontmatter keys of an existing entry in that folder,keep its comments, and fill in my values. Use a file name that makes a good URL. Then create thefrench and arabic versions with the same file name in the french/ and arabic/ folders, and runnpm run astro-check.