Project Structure — Data and Content
A complete reference for Dax Pro's _data and content folders: metadata, navigation, footer configuration, homepage data, posts, services, pages, and tags. Everything you edit as a site owner lives in these two folders.
Two Folders That Run Your Site
Dax Pro has a small number of folders. Of those, only two matter to a site owner:
_data/— site-wide configuration. Metadata, navigation, footer.content/— all the content on the site. Homepage, about, contact, blog posts, services, tags.
If you open nothing else, open these two. Every text you see on your rendered site comes from a file in one of these folders. If you can edit YAML and Markdown, you can run the entire site without ever opening a template or touching C#.
This chapter documents exactly what lives in _data/ and content/, how the folder structure maps to URLs, and what each file is responsible for. It does not cover templates or the DAX engine — those belong to the developer guide. This chapter is for the person running the site.
The Full Project Directory at a Glance
Before diving into the two folders, here is the complete project structure so you know where everything sits:
dax-pro/
├── _data/ ← site configuration (this chapter)
├── content/ ← all content (this chapter)
├── templates/ ← layouts and partials (developer guide)
├── public/ ← CSS, JS, images (developer guide)
├── site/ ← generated output (gitignored)
├── Dax.csproj ← C# project file
├── Program.cs ← the DAX engine
├── README.md ← quick start
├── LICENSE ← commercial license
├── netlify.toml ← Netlify deployment config
└── vercel.json ← Vercel deployment config
The two folders this chapter covers are _data/ and content/. Everything else either belongs to the developer workflow (templates, public, Program.cs) or is a configuration file for deployment platforms (netlify.toml, vercel.json).
Folder 1 — _data/
The _data/ folder holds site-wide configuration. These are values that appear on every page of the site, not just one. If the value is in _data/, it is almost certainly rendered inside the navigation bar, the footer, or every page's .
Dax Pro ships with three YAML files in _data/:
_data/
├── metadata.yaml
├── nav.yaml
└── footer.yaml
YAML is the format. It is whitespace-sensitive, so indentation matters. Two spaces per level, never tabs. Quote string values that contain special characters or start with a symbol. The example files below show the correct syntax.
_data/metadata.yaml — Site Identity and SEO
This file describes the site itself. It is read by every page to generate the , the meta description, the OpenGraph tags, and the JSON-LD schema. Search engines and social media platforms read these values. Get them right and every page inherits correct SEO; get them wrong and every page inherits the error.
A complete metadata.yaml looks like this:
title: "Dax Pro"
description: "Enterprise .NET Static Site Generator & Decap CMS Architecture"
url: "https://daxpro.axcora.com"
icon: "/images/dax-primary-logo.webp"
image: "/images/dax-primary-logo.webp"
author: "Axcora"
social:
- name: "GitHub"
url: "https://github.com/mesinkasir/dax"
- name: "Gumroad"
url: "https://creativitaz.gumroad.com/l/dax-pro"
- name: "Fiverr"
url: "https://www.fiverr.com/creativitas/design-your-website-with-progresive-web-application"
What each field does:
| Field | Purpose | Example |
|---|---|---|
title |
Site name. Used in tags, JSON-LD publisher, OpenGraph site_name. |
"Dax Pro" |
description |
Default meta description. Used when a page has no specific description. | "Enterprise .NET Static Site Generator..." |
url |
The site's production URL. No trailing slash. Used for canonical links, sitemap, RSS, JSON-LD. | "https://daxpro.axcora.com" |
icon |
Path to the favicon. Can be .ico, .png, or .webp. |
"/images/favicon.ico" |
image |
Default OpenGraph image. 1200×630 pixels is the standard for social sharing. | "/images/og-default.jpg" |
author |
Site author name. Used in JSON-LD author and in RSS feed. |
"Axcora" |
social |
List of social profile links. Used in JSON-LD and future schema extensions. | See example |
Important rules:
url must not end with a slash. "https://example.com" is correct; "https://example.com/" will produce https://example.com//page/ in canonical links. This is a subtle bug that some analytics tools flag.icon and image must start with /. They are resolved relative to the site root. /images/favicon.ico is correct; images/favicon.ico will produce broken links on nested pages.social is a list of dictionaries. Each item has a name and a url. Add as many as you need._data/nav.yaml — Navigation Bar
This file defines three things: the brand wordmark displayed in the top-left corner, the navigation menu items, and the two call-to-action buttons on the right side of the navigation bar.
A complete nav.yaml looks like this:
brand:
symbol: ".NET"
name: "DAX"
accent: "PRO"
items:
- title: "Home"
mobile_title: "Home"
url: "/"
- title: "About"
mobile_title: "About Dax Pro"
url: "/about/"
- title: "Services"
mobile_title: "Enterprise Services"
url: "/services/"
- title: "Insights"
mobile_title: "Technical Insights"
url: "/posts/"
- title: "Tags"
mobile_title: "Architecture Tags"
url: "/tags/"
- title: "Contact"
mobile_title: "Enterprise Contact"
url: "/contact/"
secondary:
text: "Pricing"
url: "/#pricing"
cta:
text: "Deploy Dax Pro"
url: "/#contact"
What each section does:
brand — the wordmark in the top-left. Dax Pro renders three pieces: a symbol badge (.NET), a name (DAX), and an accent (PRO). The accent is colored differently to highlight it. To change the brand, change these three values. There is no logo image here — this is text.
items — the navigation links. Each item has three fields:
| Field | Purpose |
|---|---|
title |
The text shown in the desktop navigation bar |
mobile_title |
The text shown in the mobile drawer menu (may be longer) |
url |
The destination. Use / for the homepage, /page/ for other pages. |
Add, remove, or reorder items freely. The order in the YAML is the order in the navigation bar.
secondary — the secondary CTA button (a ghost button with border). Typically used for pricing or a less-prominent action. It appears to the left of the primary CTA.
cta — the primary CTA button (filled with brand color). Typically "Get Started" or "Deploy" or "Contact." This is the most prominent call to action on the site.
Important rules:
/about/, /contact/. Home is / (no extra slash). Anchor links on the homepage use /#section: /#pricing, /#contact.mobile_title field is optional. If omitted, the title is used in the mobile drawer. It exists so you can have short desktop labels and longer mobile labels, which is often better UX._data/footer.yaml — Footer Structure
This file defines the entire footer: the brand column, three link columns, the copyright line, and the legal link bar at the bottom.
A complete footer.yaml looks like this:
brand:
symbol: ".NET"
name: "DAX"
accent: "PRO"
brand_desc: "The ultra-luxurious corporate theme designed for high-velocity Microsoft .NET Static Site Generators and Decap CMS. Powered by pure semantic HTML5, CSS3, and modern engineering principles."
compatibility:
- "Microsoft .NET 8 / 9"
- "·"
- "Decap CMS 3.x"
- "·"
- "Pure HTML5"
column1:
title: "Architecture"
list:
- name: "Static Compilation"
link: "/services/"
- name: "Decap CMS Bridge"
link: "/services/"
- name: "Azure CI/CD Pipeline"
link: "/services/"
- name: "Security Audits"
link: "/about/"
- name: "Benchmark Telemetry"
link: "/tags/"
column2:
title: "Resources"
list:
- name: "Technical Insights"
link: "/posts/"
- name: "Decap CMS Guide"
link: "/posts/"
- name: "Architecture Directory"
link: "/tags/"
- name: ".NET Articles"
link: "/tags/"
- name: "Dax Core Project"
link: "https://dax.axcora.com"
column3:
title: "Company"
list:
- name: "About Dax Pro"
link: "/about/"
- name: "Enterprise Services"
link: "/services/"
- name: "Commercial Licensing"
link: "/license/"
- name: "Contact Engineering"
link: "/contact/"
- name: "SLA & Support"
link: "/contact/"
copyright: "© 2026 Dax Pro. Developed for the Microsoft .NET SSG ecosystem and Decap CMS community. All rights reserved."
legal:
- title: "Privacy Policy"
url: "/privacy/"
- title: "Terms of Service"
url: "/terms/"
- title: "License"
url: "/license/"
What each section does:
brand — the footer wordmark. Same structure as nav.yaml. It is defined separately here so the footer brand can differ from the navigation brand if desired. In practice, both usually show the same wordmark.
brand_desc — a short paragraph under the footer wordmark. Two to four sentences is typical. Keep it under 200 characters.
compatibility — a row of small tech badges. In the default theme, these appear as text separated by middle dots: Microsoft .NET 8 / 9 · Decap CMS 3.x · Pure HTML5. The middle dots (·) are literal list items. Replace or remove as needed.
column1, column2, column3 — three link columns. Each has a title (column header) and a list (the links). Each link has a name (display text) and a link (URL).
copyright — the copyright line, shown at the bottom of the footer.
legal — the legal link bar. A horizontal list of small links in the very bottom of the footer. Typically privacy, terms, and license.
Important rules:
"Privacy Policy" → "/privacy/" is correct."https://dax.axcora.com" in link opens in a new tab if the template marks it as external. In Dax Pro, all footer links open in place — the destination is determined by the URL itself, not a flag.What Is Not in _data/
The _data/ folder holds site-wide configuration. It does not hold:
content/)public/images/)templates/)netlify.toml and vercel.json)If you are looking for the text of a specific blog post or the layout of a specific page, it is not in _data/.
Folder 2 — content/
The content/ folder holds every piece of content on the site. Every page, every post, every service, every tag — all of it originates as a Markdown file in content/.
The structure of content/ determines the URL of every page. Dax Pro uses a simple rule: the file's path within content/ becomes its URL path.
content/about.md → /about/
content/contact.md → /contact/
content/posts/hello-world.md → /posts/hello-world/
content/services/design.md → /services/design/
A file named index.md inside a folder becomes the folder's index. So:
content/posts/index.md → /posts/
content/docs/index.md → /docs/
Dax Pro ships with the following content structure:
content/
├── index.md ← homepage
├── about.md ← /about/
├── contact.md ← /contact/
├── privacy.md ← /privacy/
├── terms.md ← /terms/
├── license.md ← /license/
├── posts.md ← controller for /posts/
├── posts/ ← blog posts
│ ├── first-post.md
│ ├── second-post.md
│ └── ...
├── services.md ← controller for /services/
├── services/ ← service detail pages
│ ├── service-one.md
│ └── ...
└── tags.md ← controller for /tags/
Each type of file has a specific purpose. The rest of this chapter explains them.
Content Files Are Markdown With Frontmatter
Every file in content/ is a Markdown file with a frontmatter block at the top. Frontmatter is YAML between two sets of triple dashes. The content after the frontmatter is the Markdown body.
---
layout: "post.dax"
title: "My First Post"
description: "A short description"
date: 2026-05-04
Body content starts here
This is the Markdown body. It is rendered into HTML by the engine.
The frontmatter is required. If it is missing or malformed, the entire file will render as plain text instead of as a page. Two rules are absolute:
Rule 1: The file must start with --- on its own line. No spaces before, no BOM character, no other text. Just ---.
Rule 2: The frontmatter must end with --- on its own line, followed by a blank line. The blank line after the closing --- is not optional. If you omit it, the closing --- is treated as part of the body, and the frontmatter is not parsed.
Both rules exist because of how Markdown parsers work. They are not Dax Pro quirks — they are the standard Markdown frontmatter format used by Jekyll, Hugo, Eleventy, and every other static site generator.
content/index.md — The Homepage
The homepage lives at content/index.md. This is the only file that produces the site root (/). Its structure is different from other pages because the homepage is composed of many sections: hero, trust, solutions, performance, showcase, pricing, insights, contact.
The frontmatter of index.md is the longest in the project. It contains nested data for every section:
---
layout: home.dax
title: "Dax Pro — Enterprise .NET Static Site Generator & Decap CMS"
description: "Ultra-luxurious, corporate pure HTML/CSS/JS theme..."
image: "https://images.unsplash.com/..."
hero:
kicker: "Enterprise .NET Static Site Generator"
title_prefix: "High-Velocity Static Architecture for"
title_highlight: "Microsoft .NET"
title_suffix: "& Decap CMS"
lead: "Dax Pro transforms..."
cta_primary:
text: "Request Enterprise Evaluation"
url: "#contact"
# ... and so on
The body of index.md is usually empty (or contains only a Markdown heading) because all content is expressed in the frontmatter, and each section is rendered by its own partial template.
Editing the homepage means editing the frontmatter in index.md. There are no partial templates to touch. Change hero.title_prefix to change the headline. Change pricing.tier2.price to change the price. Change contact.email to change the email address.
content/about.md, contact.md, privacy.md, terms.md, license.md — Static Pages
These are static pages: single pages that are not part of a collection. Each one produces a single URL:
about.md → /about/contact.md → /contact/privacy.md → /privacy/terms.md → /terms/license.md → /license/Each has the same structure:
---
layout: "page.dax"
title: "About Dax Pro"
breadcrumb: "About"
description: "A short description for SEO"
cta:
title: "Ready to get started?"
description: "..."
button1_text: "Buy Now"
button1_url: "/#pricing"
button1_class: "dax-btn-primary"
button2_text: "Contact"
button2_url: "/contact/"
button2_class: "dax-btn-secondary"
Markdown body
This is where the page content lives. Write normally with Markdown.
The frontmatter has five fields:
| Field | Purpose |
|---|---|
layout |
Which template renders this page. For static pages, always page.dax. |
title |
The page's title. Used in , the H1, and the breadcrumb. |
breadcrumb |
Optional short label for the breadcrumb bar. If omitted, title is used. |
description |
Meta description for SEO. Aim for 150–160 characters. |
cta |
Optional call-to-action box at the bottom of the page. Omit for legal pages. |
The body of the file is the page's content in Markdown. Standard Markdown applies: headings, paragraphs, bold, italic, lists, links, images, code blocks, blockquotes.
The cta section is optional. Legal pages like privacy.md and terms.md usually omit it. Marketing pages like about.md include it to drive conversion.
content/posts/ — Blog Collection
The posts/ folder holds blog articles. Every .md file inside posts/ becomes a blog post at /posts/{filename}/.
content/posts/why-static-sites.md → /posts/why-static-sites/
content/posts/blazor-vs-dax.md → /posts/blazor-vs-dax/
content/posts/decap-cms-guide.md → /posts/decap-cms-guide/
Each post has a standard frontmatter:
---
layout: "post.dax"
title: "Why Static Sites Beat Dynamic CMS"
description: "A detailed look at why static site generators win for content"
image: "https://images.unsplash.com/..."
date: 2026-05-04
category: "Architecture"
read_time: "6 min read"
read_more: "Read Analysis"
author: "Axcora"
tags: ["dotnet", "static", "performance"]
excerpt: "A short summary shown in the blog listing card"
Markdown body of the post goes here.
Fields explained:
| Field | Purpose |
|---|---|
layout |
Always post.dax for blog posts. |
title |
Post title. Used in , H1, listing card, prev/next nav. |
description |
Meta description for SEO. |
image |
Featured image. Used as OpenGraph image and as the listing card thumbnail. |
date |
Publication date in YYYY-MM-DD format. Used for sorting. |
category |
A single category name for the post. Shown in the meta line. |
read_time |
Human-readable read estimate. You determine this; the engine does not calculate it. |
read_more |
Label for the "read more" link on the listing card. Defaults to "Read Article" if omitted. |
author |
Author name. Shown in the meta line. |
tags |
List of tags. Must be lowercase — tags are used as URL slugs. |
excerpt |
Short summary shown on the listing page. |
Important: tags must be lowercase. A tag "DotNet" produces a URL /tags/DotNet/, but the actual tag page is generated at /tags/dotnet/. Uppercase tags break the tag links. Always write tags in lowercase: "dotnet", "razor", "blazor", "decapcms".
Post ordering: posts are sorted by date in descending order. The most recent post appears first on /posts/ and in the homepage's Insights section. If two posts share a date, they are ordered alphabetically by URL.
Adding a new post: create a new .md file in content/posts/, fill in the frontmatter, write the body, and rebuild. The post will appear in the listing automatically.
Removing a post: delete the .md file from content/posts/ and rebuild. The post will no longer appear.
content/services/ — Service Collection
The services/ folder holds service detail pages. It works exactly like posts/, but for services rather than articles.
content/services/dotnet-architecture.md → /services/dotnet-architecture/
content/services/cms-migration.md → /services/cms-migration/
A service has this frontmatter:
---
layout: "service.dax"
title: ".NET Static Site Generator Architecture"
description: "Custom .NET SSG architecture for enterprise teams"
image: "https://images.unsplash.com/..."
index: "01. COMPILATION"
read_more: "Explore Solution Architecture"
date: 2026-05-04
tags: ["dotnet", "razor", "blazor"]
cta:
title: "Need a custom .NET SSG architecture?"
description: "Hire a dedicated .NET engineer for bespoke setup."
button1_text: "Hire on Fiverr"
button1_url: "https://www.fiverr.com/..."
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"
Markdown body of the service page.
Fields explained:
| Field | Purpose |
|---|---|
layout |
Always service.dax for service pages. |
title |
Service title. |
description |
Meta description and card summary. |
image |
Optional feature image. |
index |
A short badge like "01. COMPILATION". Shown above the title. |
read_more |
Label for the listing card's "read more" link. |
date |
Sort order for the services listing. |
tags |
List of lowercase tags. |
cta |
Call-to-action box at the bottom of the service page. Two buttons supported. |
The cta block is a nested object with two buttons. Every service should include it, because the service detail page's primary conversion point is the CTA at the bottom.
Service ordering is determined by date, like posts. The service with the most recent date appears first in /services/.
Controller Files — posts.md, services.md, tags.md
Three files in content/ look like regular Markdown but are not. They are controllers — files that tell Dax Pro to generate a paginated listing for a collection.
content/posts.md:
---
layout: "posts-list.dax"
title: "Engineering Publications & Blueprints"
breadcrumb: "Technical Insights"
description: "Architectural analyses, performance benchmarks, and headless content modeling strategies."
collection: "posts"
pagination: 6
content/services.md:
---
layout: "services-list.dax"
title: "Specialized .NET SSG Architecture Services"
breadcrumb: "Enterprise Services"
description: "End-to-end consulting, migration roadmaps, and custom theme engineering."
collection: "services"
pagination: 6
content/tags.md:
---
layout: "tags.dax"
title: "Architecture & Subject Index"
breadcrumb: "Taxonomy Directory"
description: "Browse specialized technical subjects across the Dax Pro ecosystem."
How controllers work:
The collection field names the folder whose items should be listed. collection: "posts" means "list the items in content/posts/". The pagination field says how many items to show per page.
With pagination: 6 and 13 posts, Dax Pro generates:
/posts/ with posts 1–6/posts/page/2/ with posts 7–12/posts/page/3/ with post 13The tags.md file works differently: it does not have a collection field. It is the index for all tags, generated automatically from the tags fields across all content.
Do not delete controller files. If posts.md is missing, the /posts/ listing will not be generated, and every blog post will be reachable only by direct URL. The controller is what creates the listing page.
Do not add a collection field to non-controller files. If you add collection: "posts" to content/about.md, Dax Pro will think about.md is a second posts controller and generate a duplicate listing.
Content File Naming Rules
File names become URL slugs. Keep them lowercase, use hyphens for spaces, and avoid special characters.
Good file names:
why-static-sites-win.md
decap-cms-enterprise-guide.md
dotnet-architecture.md
Bad file names:
Why Static Sites Win.md ← spaces break URLs
Decap_CMS_Guide.md ← underscores are valid but ugly
dotnet architecture.md ← space breaks URL
The URL produced is the filename minus .md, lowercased, with spaces converted to hyphens. Following the good naming convention above means the URL is exactly what you expect.
How the Two Folders Connect
To understand how _data/ and content/ work together, consider what happens when someone visits https://yoursite.com/about/:
1. Dax Pro looks for content/about.md
2. It reads the frontmatter — title, description, layout: page.dax, optional cta
3. It also reads _data/metadata.yaml for the site title, meta description fallback, URL, and image
4. It reads _data/nav.yaml for the navigation bar
5. It reads _data/footer.yaml for the footer
6. It applies the page.dax layout, injecting the frontmatter values and the _data/ values
7. It writes the final HTML to site/about/index.html
The result: a page whose content is unique (from content/about.md) but whose navigation, footer, and SEO defaults come from _data/. Change _data/nav.yaml, and every page updates. Change content/about.md, and only /about/ updates.
This separation is why _data/ exists. If navigation were defined in every Markdown file, you would have to change it in a hundred places. Because it lives in one YAML file, you change it once.
What You Should Edit, and What You Should Not
Now that you know the two folders, here is a quick decision table for day-to-day edits.
| If you want to change... | Edit this file |
|---|---|
The site title shown in |
_data/metadata.yaml → title |
| The site description for SEO | _data/metadata.yaml → description |
| The favicon | _data/metadata.yaml → icon (and place the file in public/images/) |
| The OpenGraph image | _data/metadata.yaml → image |
| Navigation links | _data/nav.yaml → items |
| The brand wordmark in the navbar | _data/nav.yaml → brand |
| The primary CTA button | _data/nav.yaml → cta |
| Footer link columns | _data/footer.yaml → column1, column2, column3 |
| The footer copyright line | _data/footer.yaml → copyright |
| The privacy and terms links | _data/footer.yaml → legal |
| The homepage text | content/index.md (frontmatter) |
| The about page text | content/about.md (frontmatter + body) |
| A blog post | content/posts/{slug}.md |
| A service detail page | content/services/{slug}.md |
| The blog listing page title | content/posts.md → title |
| The number of posts per page | content/posts.md → pagination |
If the file is under _data/, your change affects every page. If the file is under content/, your change affects only that page.
Rules That Prevent Most Bugs
These four rules prevent 90% of the bugs users hit on their first day.
Rule 1: Files must start with ---. No spaces, no blank lines, no BOM. Just --- on line 1.
Rule 2: The closing --- must be followed by a blank line. The blank line separates frontmatter from body. Without it, the body is not parsed as Markdown.
Rule 3: Quote all YAML values that contain colons, hashes, or start with symbols. title: "My: Title" is correct. title: My: Title is a parse error.
Rule 4: Use LF line endings, not CRLF. Windows editors default to CRLF, which the DAX YAML parser does not accept. Configure your editor to save with LF (see the Installation chapter). If you forget, the frontmatter will render as plain text on the page — a confusing symptom for a simple cause.
If your page shows raw YAML on the rendered site — with --- and title: visible in the body — one of these four rules was broken. Fix the file and rebuild.
What You Have Now
After reading this chapter, you understand:
_data/ and content/_data/ holds three YAML files: metadata.yaml, nav.yaml, footer.yamlcontent/ holds Markdown files with frontmatter, organized by URL pathindex.md is the homepage; about.md etc. are static pagesposts/ and services/ are collections with their own controller filesThe next chapter, Configuration, walks through editing _data/metadata.yaml, _data/nav.yaml, and _data/footer.yaml step by step. That is the first practical task after installation — getting the site identity correct before writing content.
→ Continue to Configuration