Content that survives: why your facts live in one file
Why the prices, stages and questions on a website should live in one data file rather than being typed into page layouts, what that changes when you need an edit, and what a Git-backed content workflow means for you. Uses this site as the worked example. Fully referenced.
The two earlier posts in this series were about code: what React is and where we let it run. This one is about words. Specifically, the words on your site that are facts: prices, timelines, the steps in your process, the answers to common questions. Where those words are stored decides how hard they are to change, who can change them, and whether anyone can tell what changed. This site is the example.
The problem: a price that lives in five places
Most websites are built by typing text straight into the page layouts. The price goes into the pricing table. The same price goes into the question “how much does a website cost?” further down, and again in a footer line. The site looks fine.
Then the price changes. Someone edits the table and forgets the question. For a while the site quotes two prices, and the visitor who notices is the one you least want to notice. The fix is not discipline. The fix is to make the fact exist once.
One file for the facts
On this site, every piece of copy that is a fact lives in a single data file. It holds the five stages of our process, from brief to live, with what you do and what we do at each one. It holds the deliverables you sign off at each stage. It holds the three pricing rows, the eight things included in every build, and the seven questions and answers on the home page. The page layouts do not contain any of that text. They read the file and lay it out.
When a price changes, one line in one file changes, and the pricing table and the question and answer update together because they were never separate copies. The person making the change does not need to know how the page is built or where the price appears. They need to know which line to edit. And the old value is still in the history, which is the next part.
Every change is a commit
The files that make up this site are kept in Git. GitHub’s introduction defines the category: “A version control system, or VCS, tracks the history of changes as people and teams collaborate on projects together”, and “Git is the most popular distributed version control system”[1]. In Git, “the file history appears as snapshots in time called commits”[1]. Each commit answers four questions: “Which changes were made? Who made the changes? When were the changes made? Why were changes needed?”[1]
The official Git book explains what a commit stores: “every time you commit, or save the state of your project, Git basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot”[2]. Two properties of that design matter for a business. Integrity: “it’s impossible to change the contents of any file or directory without Git knowing about it”[2]. And safety: “It is hard to get the system to do anything that is not undoable or to make it erase data in any way”[2].
For your site this means a price change is a commit with a date, an author and a one-line reason. The previous price is not overwritten; it is the previous snapshot, and a wrong change is undone by going back to it. A site edited through a page builder’s text boxes usually has none of this: the old text is gone the moment someone clicks save.
The hosting closes the loop. This site is deployed on Cloudflare Pages from its Git repository, and “Cloudflare will automatically deploy your code every time you push a change to a branch”[3]. It also generates “preview URLs for a commit to any branch in the repository without affecting your production deployment”[3], so a change can be checked on a private address before it goes live, and the commit that went live is on record.
Blog posts as files with a schema
Facts are one kind of content. Articles like this one are another, and they use a different container: a content collection. Astro, the framework this site is built on, defines the idea in one line: “A content collection is a set of related, structurally identical data”[4]. Each post is a Markdown file, which Astro notes “is commonly used to author text-heavy content like blog posts and documentation”[5]. At the top of each file is a short block of frontmatter, where you “define custom properties such as a title, description, and tags”[5].
The part that protects you is the schema. This site’s collection is defined in one configuration file. It uses Astro’s glob loader, which “fetches entries from directories of Markdown, MDX, Markdoc, JSON, YAML, or TOML files”[4], pointed at the blog folder. The schema then says what every post must carry: a title and a description, both required; a date; an optional updated date; an author, which defaults to Dispatch Web; an optional series name; a list of tags, empty if none; and a draft flag, off by default. Astro’s documentation explains the purpose: “Schemas enforce consistent frontmatter or entry data within a collection through Zod validation”[4], and “If any file violates its collection schema, Astro will provide a helpful error to let you know”[4].
In plain terms: a post with no title, or a date typed as “next Tuesday”, does not get published quietly with a blank heading. The build stops and says which file is wrong and why. The schema also gives the rest of the site a guarantee. Because Astro “will automatically generate and apply a TypeScript interface” from it[4], the blog index, the article template and the RSS feed all know exactly what fields a post has, and a post marked as a draft is filtered out of all three by the same one-word test.
Before and after
The table compares the two ways of keeping a fact on a site, using a price change as the example.
| Copy typed into page layouts | Copy in one data file, in Git | |
|---|---|---|
| How a price change happens | Find every place the price appears, edit each one, hope none were missed | Edit one line in one file; every page that shows the price updates |
| Who can do it | Whoever knows the layout tool and where each copy lives | Anyone who can edit a text file, or use the admin screen described below |
| What history exists | Usually none; the old text is overwritten on save | A commit with the date, the author, the reason and the previous value[1] |
| What can break | Two pages quoting different prices; a layout nudged by accident while editing text | The build refuses a change that does not fit the schema, before it goes live[4] |
The right-hand column is not a feature we add on request. It is how this site is built, and how we build client sites by default.
If you want to edit it yourself
None of this requires you to learn Git. Once a site is live, you send content changes when you need them and we make them. Each one becomes a commit.
If you would rather make routine edits yourself, the same files can sit behind a simple admin screen. Astro’s guide explains the general idea: “A Content Management System lets you write content and manage assets outside of your Astro project”, and for a site like this you want a headless one, which “helps you write your content, but doesn’t generate a site that displays it”[6]. The option we offer for this is a Git-backed CMS. Decap CMS describes itself as “an open source content management system for your Git workflow”[7], where “content is stored in your Git repository alongside your code for easier versioning”[7]. Its own summary of what it does is the point of this whole post: “you’re basically adding a tool for content editors to make commits to your site repository without touching code or learning Git”[7].
In practice it “adds a route (typically /admin) to your project that will load a React app to allow authorized users to manage content directly from the deployed website”, and it “will commit changes directly to your Astro project’s source repository”[8]. You log in, change the text in a form, and save. Behind the form, that save is a commit, the schema still checks it, and the hosting still deploys it. The history is the same whether the edit came from us or from you.
The trade-off is worth naming. An admin screen is a second thing to maintain and a second way to log in, so we do not add it to every site. For text that changes a few times a year, sending us the change is simpler. For a blog you want to write yourself, the admin screen earns its place. It is a checkbox in the brief, not a rebuild later.
What this means for you
When you are comparing quotes, ask one question: where will the price live? If the answer is “in the page”, ask how many pages, and who keeps them in step. If the answer is “in one place, with a history”, you are being offered the arrangement described here, and it is the one to insist on.
If you are planning a build, the brief builder takes about three minutes. It asks whether you want to edit content yourself, and the answer comes back with a fixed price. The speed figures for this site are on the home page, stored, as you would now expect, in a file with a date on it.
Reference list
All sources accessed 2 September 2026.
- GitHub (n.d.) About Git. GitHub Docs. https://docs.github.com/en/get-started/using-git/about-git
- Chacon, S. and Straub, B. (2014) 'Getting Started: What is Git?', in Pro Git, 2nd edn. git-scm.com. https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F
- Cloudflare (n.d.) Git integration. Cloudflare Pages documentation. https://developers.cloudflare.com/pages/configuration/git-integration/
- Astro (n.d.) Content collections. Astro documentation. https://docs.astro.build/en/guides/content-collections/
- Astro (n.d.) Markdown in Astro. Astro documentation. https://docs.astro.build/en/guides/markdown-content/
- Astro (n.d.) Use a CMS with Astro. Astro documentation. https://docs.astro.build/en/guides/cms/
- Decap CMS (n.d.) Overview. Decap CMS documentation. https://decapcms.org/docs/intro/
- Astro (n.d.) Decap CMS & Astro. Astro documentation. https://docs.astro.build/en/guides/cms/decap-cms/