Services Collections — Individual Service Pages

Create and edit individual service detail pages in Dax Pro: frontmatter fields, CTA blocks, ordering, tags, and Markdown body. Each file in content/services/*.md becomes a service page at /services/{slug}/.

What a Service Collection Is

Every service your business offers gets its own page. A design agency might have "Brand Design," "Web Development," and "SEO Consulting." A .NET consultancy might have "Static Site Architecture," "Migration," and "Accessibility Audits." Each of those is a service.

In Dax Pro, each service is a single Markdown file inside the content/services/ folder. The filename becomes the URL:

content/services/dotnet-architecture.md      → /services/dotnet-architecture/

content/services/decap-cms-workflow.md → /services/decap-cms-workflow/

content/services/legacy-cms-migration.md → /services/legacy-cms-migration/

Every service page shares the same template (service.dax), the same layout, and the same frontmatter structure. The differences are the content: title, description, body, CTA, and tags.

When you add a new file to content/services/, the page appears automatically. When you delete one, it disappears. When you change the date, the listing order changes. There is no separate index to update — the services listing at /services/ pulls automatically.

This chapter covers:

1. The frontmatter structure — every field in every service

2. Writing the Markdown body — the content of the page

3. The CTA block — the call-to-action at the bottom

4. Tags — how they work and why they matter

5. Ordering — how services appear in the listing

6. Creating a new service — from CMS and from file

7. Common mistakes — the patterns that break service pages


The Frontmatter Structure

Every service file starts with a frontmatter block. Here is a complete example:

---

layout: "service.dax"

title: ".NET Static Site Generator Architecture"

description: "Custom C# generator setup, Razor component layout engineering, and sub-second batch compilation tuning for high-page count corporate repositories."

image: "https://images.unsplash.com/photo-1518770660439-4636190af475?w=1200&q=80&auto=format&fit=crop"

index: "01. COMPILATION"

read_more: "Explore Solution Architecture"

date: 2026-03-28

tags: ["dotnet", "razor", "blazor", "staticsitegenerator", "enterprise"]

cta:

title: "Need a custom .NET SSG architecture built for your team?"

description: "Hire a dedicated .NET engineer for bespoke generator setup, Razor layout engineering, or a scoped pilot project."

button1_text: "Hire on Fiverr"

button1_url: "https://www.fiverr.com/creativitas/design-your-website-with-progresive-web-application"

button1_class: "dax-btn-primary"

button2_text: "Order Dax Pro Theme"

button2_url: "https://creativitaz.gumroad.com/l/dax-pro"

button2_class: "dax-btn-secondary"


Every field explained:

Field Purpose Required?
layout The template used to render the page. Must be service.dax. Yes
title The page's H1, browser title, and listing card title. Yes
description Meta description, listing card text, and OpenGraph description. Yes
image Featured image. Used as OpenGraph image and in the listing card (if the template supports it). Optional
index Small badge text shown above the title on the detail page. Example: 01. COMPILATION. Optional
read_more The "read more" label on the listing card. Defaults to "Explore Solution Architecture" if omitted. Optional
date Publication date in YYYY-MM-DD format. Determines ordering. Yes
tags List of lowercase tags. Each becomes a tag page at /tags/{tag}/. Optional
cta Call-to-action block at the bottom of the page. Optional but recommended

Do not change layout. It must always be service.dax. Changing it to another layout will break the page or produce a 404.


Writing the Markdown Body

After the closing --- of the frontmatter, the body begins. This is Markdown, and it renders as the main content of the service page.

A well-structured service body has:

1. An opening section — one paragraph explaining what the service delivers

2. A scope or deliverables section — bulleted list of what is included

3. A differentiation section — why this service is better than alternatives

4. A process or timeline section — optional, how it works

5. A closing section — call to action (though the CTA block below handles this)

Example body:

## What This Service Delivers

A production-grade .NET static site generator tailored to your content model, deployed to your infrastructure of choice.

Scope of Work

  • Custom C# generator pipeline tuned for your page volume
  • Razor layout engineering for your design system
  • Batch compilation optimization targeting sub-second builds
  • Markdown frontmatter schema design
  • Content collection and taxonomy architecture
  • Deployment configuration for Netlify, Vercel, Azure Static Web Apps, or Cloudflare Pages
  • Why .NET Teams Choose Static Over Blazor WASM

    Blazor WASM ships a 512KB+ runtime and pays a 2-second boot cost before the first paint. For marketing sites, documentation portals, and enterprise content — that budget is wasted.

    A compiled .NET static site generator produces pure HTML at build time. Zero hydration. Zero WASM. Zero client-side C# runtime. Lighthouse 100 by default.

    Deliverables

  • Full source code with perpetual commercial license
  • Build and deploy documentation
  • Post-launch support window

Markdown features supported:

  • ## and ### for section headings
  • Standard paragraphs
  • Bulleted lists with -
  • Numbered lists with 1., 2., 3.
  • bold and italic
  • link text for inline links
  • ` inline code for code references
  • Fenced code blocks with triple backticks
  • Blockquotes with >
  • Writing quality matters. Service pages are read by potential clients deciding whether to hire you. Unlike blog posts, which may be skimmed, service pages are usually read carefully. Aim for 400–800 words — long enough to establish credibility, short enough that readers finish.


    The CTA Block

    The CTA (call-to-action) block appears at the bottom of every service page, after the Markdown body. It is a dark gradient box with a title, description, and two buttons. This is the conversion point — the moment a reader who has finished the page decides whether to hire you.

    A complete CTA block:

    cta:
    

    title: "Need a custom .NET SSG architecture built for your team?"

    description: "Hire a dedicated .NET engineer for bespoke generator setup, Razor layout engineering, or a scoped pilot project."

    button1_text: "Hire on Fiverr"

    button1_url: "https://www.fiverr.com/creativitas/design-your-website-with-progresive-web-application"

    button1_class: "dax-btn-primary"

    button2_text: "Order Dax Pro Theme"

    button2_url: "https://creativitaz.gumroad.com/l/dax-pro"

    button2_class: "dax-btn-secondary"

    Fields:

    Field Purpose
    title Heading in the CTA box
    description Paragraph under the heading
    button1_text First button label
    button1_url First button destination
    button1_class dax-btn-primary (filled) or dax-btn-secondary (outlined)
    button2_text Second button label
    button2_url Second button destination
    button2_class dax-btn-primary or dax-btn-secondary

    Design pattern: the CTA typically promotes a specific action related to that service. For a service that requires custom work, button1 goes to a "Hire me" page (Fiverr, Upwork, or a contact form). button2 goes to a related product (like the Dax Pro theme itself), so the reader can purchase immediately if they decide self-service is the right fit.

    Both buttons are optional. If you only want one button, omit button2_text and button2_url. The template renders only button1. If you want no CTA at all, remove the entire cta: block. The page renders without a bottom box.

    Different buttons for different services: each service can point its CTA to a different destination. A migration service might point to a migration-specific contact form; a brand customization service might point to a portfolio page.

    Button classes:

  • dax-btn-primary — filled with brand color. Use for the main action.
  • dax-btn-secondary — outlined. Use for the secondary action.
  • You can add dax-btn-lg for larger buttons: "dax-btn-primary dax-btn-lg". This is optional; the standard size is fine for most CTAs.

  • Tags

    Tags on a service work the same as tags on a blog post. They create entries in the /tags/ directory. If a service has tags: ["dotnet", "razor"], it appears in both /tags/dotnet/ and /tags/razor/.

    Tags must be lowercase. A tag "DotNet" produces a URL /tags/DotNet/, but the tag page is generated at /tags/dotnet/. Uppercase tags break the tag links.

    Common service tags:

    dotnet, razor, blazor, decapcms, static, enterprise, migration,
    

    azure, cicd, performance, accessibility, wcag, theming, brand,

    audit, compliance, headless, csharp

    Why tags matter:

  • Cross-linking — a reader on /services/legacy-cms-migration/ sees it tagged migration and dotnet. Clicking either tag shows all services and posts with that tag. This creates discovery paths.
  • SEO — tag pages are indexable. A /tags/migration/ page collects all migration-related content, giving you a dedicated page for that keyword.
  • Taxonomy — tags express what your offering covers, not just how you describe it.
  • Number of tags per service: two to six is typical. One is fine; twenty is too many. Choose tags that describe both what the service is (migration) and how it relates to your positioning (dotnet, enterprise).

    Do not use spaces in tags. "content migration" should be "content-migration" or "migration". Spaces break the URL.

    The tag list is generated automatically. You do not need to declare tags anywhere else. Add a tag to a service and /tags/{tag}/ appears in the build (if it did not exist already). Remove the last service with a tag and the tag page disappears.


    Ordering

    Services are sorted by date in descending order. The most recently dated service appears first in:

  • The /services/ listing page
  • Any section that lists services (currently none on the homepage by default)
  • The prev/next navigation on individual service pages
  • To control order, control date. Give the services you want first the most recent dates.

    Example:

    You have three services and want them in this order:

    1. "Architecture" (first)

    2. "Migration" (second)

    3. "Audit" (third)

    Set:

    # content/services/architecture.md
    

    date: 2026-03-15

    # content/services/migration.md
    

    date: 2026-02-15

    # content/services/audit.md
    

    date: 2026-01-15

    The dates do not need to be real publication dates. They are ordering hints. Use whatever dates produce the order you want.

    The index field does not affect ordering. It only provides a visible badge. If you want the badge and the position to match, set both consistently. For example, if "Architecture" should appear first and have badge "01. COMPILATION", set both date (most recent) and index: "01. COMPILATION".

    Changing dates in bulk: if you want to reorder many services, edit the files directly and push once. Editing through the CMS triggers one rebuild per service, which is slower.


    Creating a New Service

    Via Decap CMS

    1. Open https://yoursite.com/admin/

    2. Click 🛠 Services in the left sidebar

    3. Click New Service (top-right of the services list)

    4. Fill in the fields:

    Field Value
    Title Your service title
    Description One-sentence summary
    Image Optional featured image
    Index Badge text (e.g., 07. NEW SERVICE)
    Read More Label Link label on the listing card
    Date Set to today or a specific date for ordering
    Tags Comma-separated list of lowercase tags
    CTA → Title CTA heading
    CTA → Description CTA paragraph
    CTA → Button 1 Text First button label
    CTA → Button 1 URL First button destination
    CTA → Button 1 Class dax-btn-primary or dax-btn-secondary
    CTA → Button 2 Text Second button label
    CTA → Button 2 URL Second button destination
    CTA → Button 2 Class dax-btn-primary or dax-btn-secondary
    Body Markdown body content

    5. Click Publish

    6. Decap CMS creates content/services/{slug}.md where {slug} is derived from the title

    7. The host rebuilds and the page appears at /services/{slug}/

    Slug rules: the title determines the filename. Brand Design → brand-design.md → /brand-design/ → /services/brand-design/. Choose titles that produce the URLs you want.

    Directly in the File System

    1. Open content/services/ in VS Code

    2. Create a new file (e.g., new-service.md)

    3. Paste the frontmatter template:

    ---
    

    layout: "service.dax"

    title: "New Service Title"

    description: "One-sentence description."

    image: ""

    index: "07. NEW SERVICE"

    read_more: "Explore Solution Architecture"

    date: 2026-05-10

    tags: ["dotnet", "new"]

    cta:

    title: "Ready to get started?"

    description: "Hire me for this service."

    button1_text: "Contact"

    button1_url: "/contact/"

    button1_class: "dax-btn-primary"

    button2_text: "See Pricing"

    button2_url: "/#pricing"

    button2_class: "dax-btn-secondary"


    What This Service Delivers

    Body content goes here in Markdown.

    4. Save the file

    5. Run dotnet run -- build

    6. The page is generated at /services/new-service/


    Editing an Existing Service

    Via Decap CMS

    1. Open https://yoursite.com/admin/

    2. Click 🛠 Services

    3. Click the service you want to edit

    4. Update the fields

    5. Click Publish

    The change commits to Git, the host rebuilds, the page updates within a minute.

    Directly in the File System

    1. Open content/services/{slug}.md in VS Code

    2. Edit the frontmatter or body

    3. Save

    4. Run dotnet run -- build (or dotnet run -- start for live preview)

    5. Commit and push for production

    git add content/services/{slug}.md
    

    git commit -m "Update {service name} service"

    git push


    Deleting a Service

    Via Decap CMS

    1. Open https://yoursite.com/admin/

    2. Click 🛠 Services

    3. Click the service

    4. Click the ⋯ menu in the top-right

    5. Choose Delete entry

    6. Confirm

    Directly in the File System

    rm content/services/{slug}.md
    

    dotnet run -- build

    git add content/services/

    git commit -m "Remove {service name} service"

    git push

    The service disappears from /services/. Any tags it had that no other service or post uses disappear from /tags/.


    Common Service Collection Mistakes

    Mistake 1: Uppercase tags.

    tags: ["DotNet", "Razor"]    # wrong
    

    tags: ["dotnet", "razor"] # correct

    Uppercase tags produce tag URLs that do not exist.

    Mistake 2: Missing date.

    Without a date, the service is treated as having the oldest possible date and appears last in the listing. Always include a date.

    Mistake 3: Invalid date format.

    date: March 28, 2026    # wrong
    

    date: 2026-03-28 # correct

    The date must be YYYY-MM-DD. Anything else breaks parsing.

    Mistake 4: Missing layout.

    Without layout: "service.dax", the page uses the default layout, which is likely wrong or blank. Always include the layout.

    Mistake 5: Adding a collection field.

    collection: "services"    # wrong on individual service files
    

    The collection field is for controllers only. Adding it to an individual service file turns it into a controller, which breaks both files.

    Mistake 6: Bad CTA URLs.

    If button1_url points to a 404 (a page that does not exist), the CTA leads nowhere. Test the URL before publishing.

    Mistake 7: Empty CTA fields.

    cta:
    

    title: "Ready to get started?"

    button1_url: "" # button renders with no destination

    A button with an empty URL renders as a clickable element that does nothing. Either fill in the URL or remove the button entirely.

    Mistake 8: Very long titles.

    Custom .NET Static Site Generator Architecture and Deployment Services for Enterprise Teams becomes a long URL. Shorten the title or accept the long slug.

    Mistake 9: Duplicate slugs.

    Two services named Consulting and Consulting (trailing space) both become consulting.md — one overwrites the other. Ensure unique titles.

    Mistake 10: Forgetting the body.

    A service with a title, description, and CTA but no body is a near-empty page. It shows the header, an empty content area, and the CTA. The body is what establishes credibility.


    Service Page Rendering

    When a visitor opens /services/dotnet-architecture/, they see:

    1. Page header — breadcrumb (Home / Services / Title), optional index badge, title, and description

    2. Body content — rendered from Markdown

    3. CTA block — dark gradient box with title, description, and buttons

    4. Prev/next navigation — links to adjacent services by date

    The breadcrumb — a small navigation line at the top: Home / Services / .NET Static Site Generator Architecture. Clicking Home goes to /, clicking Services goes to /services/.

    The index badge — the index field, shown as a small label above the title. Example: 01. COMPILATION. This gives a visual rhythm to the page, suggesting a numbered series of services.

    The prev/next navigation — at the bottom, after the CTA. Shows "← Previous Service" and "Next Service →". Clicking goes to the adjacent service by date. The most recent service is the "first" in the listing, so its "Previous" is the second-most-recent, and so on. The oldest service has no "Previous" and only a "Next".


    Verifying a Service Page

    After creating or editing, verify:

    1. URL works — navigate to /services/{slug}/. The page loads.

    2. Title — browser tab and H1 match the title.

    3. Breadcrumb — shows Home / Services / Title.

    4. Index badge — if set, appears above the title.

    5. Description — view source, confirm matches.

    6. Body — all Markdown renders correctly (headings, lists, links, code).

    7. CTA — if configured, the dark box with title, description, and buttons appears.

    8. Prev/next — if there are adjacent services, prev/next links show.

    9. Listing — the service appears in /services/ in the correct order.

    10. Tags — if the service has tags, clicking one shows the tag page including this service.

    11. Mobile — resize browser. Content stacks, buttons stack, images scale.

    If a service page shows raw YAML in the browser, the frontmatter is malformed. Check:

  • File starts with --- on line 1
  • Closing --- followed by blank line
  • All quoted values are properly closed
  • No tabs (only spaces)
  • Unix line endings (LF, not CRLF)

  • What You Have Now

    After this chapter, you can:

  • ✅ Understand what a service collection is
  • ✅ Create a new service page from Decap CMS or the file system
  • ✅ Edit existing services with correct frontmatter
  • ✅ Write body content in Markdown
  • ✅ Configure the CTA block with one or two buttons
  • ✅ Add tags (lowercase) that create tag pages
  • ✅ Control ordering via date
  • ✅ Delete services cleanly
  • ✅ Verify rendering, listing, and prev/next navigation
  • ✅ Fix the ten most common service collection mistakes
  • Individual service pages are done. The next chapter covers the Blog Controller — the file that generates /posts/` as a paginated listing of blog articles.

    → Continue to Blog Controller