Plan & Pricing Data
What Is This Section?
Section titled “What Is This Section?”The pricing page (/pricing/) is different from the homepage. Instead of one JSON file, it uses two:
src/data/pricing/data.json— the content of the page (titles, descriptions, hero images, CTA buttons).src/data/pricing/pricing.json— the price list (the actual pricing tiers).
This separation is intentional. The page has two concerns:
- Content — the story, the hero, the call-to-action.
- Price list — a repeatable list of tiers that could change independently.
By splitting them, you can update prices without touching the page copy, and vice versa.
Where They Live
Section titled “Where They Live”src/data/├── plan/│ └── data.json ← page content└── pricing/ └── pricing.json ← price tiersBoth files are imported by the same MDX page: src/content/docs/plan.mdx.
File 1 — plan/data.json
Section titled “File 1 — plan/data.json”This file describes the page as a whole: its meta info, hero images, and two big CTA blocks.
Top-level keys
Section titled “Top-level keys”| Key | Type | Purpose |
|---|---|---|
url | string | Canonical URL for this page |
title | string | Page title (browser tab + SEO) |
description | string | Meta description + hero subtitle |
intro | string | The main hero headline |
icon | string | Favicon-style icon |
image | string | Small hero illustration |
hero_image | string | Large hero illustration |
themes | string | Title of the first CTA block |
themes_text | string | Description of the first CTA block |
themes_button | string | Button label for the first CTA |
themes_link | string | Button URL for the first CTA |
hire | string | Title of the second CTA block |
hire_text | string | Description of the second CTA block |
hire_button | string | Button label for the second CTA |
hire_image | string | Illustration for the second CTA |
hire_link | string | Button URL for the second CTA |
Notice the pattern: one section = title + text + button + link + image. This repeats for both the “Buy Template” block and the “Hire” block.
Example — the Buy Template block
Section titled “Example — the Buy Template block”"themes": "Buy Template - $65","themes_text": "Complete Astro Docus source code...","themes_button": "Buy Now - $65","themes_link": "https://creativitaz.gumroad.com/l/starlightastrodocus"Example — the Hire block
Section titled “Example — the Hire block”"hire": "Need Custom Setup?","hire_text": "Hire for installation, CMS integration...","hire_button": "Hire on Fiverr","hire_image": "/src/assets/webdeveloperastrojs.svg","hire_link": "https://www.fiverr.com/creativitas/design-modern-documentation-website-astro-js-stalight"Changing the button text or link is a matter of editing one string in data.json.
File 2 — pricing/pricing.json
Section titled “File 2 — pricing/pricing.json”This file is much simpler. It contains only a single array — resources — that lists every pricing tier.
{ "resources": [ { "title": "Basic", "text": "Basic package - Astro Docus template source code...", "price": "$65", "link": "https://creativitaz.gumroad.com/l/starlightastrodocus" }, { "title": "Standard", "text": "Standard package - Template source code + Tina CMS...", "price": "$105", "link": "https://www.fiverr.com/creativitas/..." } ]}Each tier has four fields
Section titled “Each tier has four fields”| Field | Type | Purpose |
|---|---|---|
title | string | Tier name (Basic, Standard, Premium…) |
text | string | Short description of what is included |
price | string | Display price (can be "$65" or "Custom") |
link | string | Where the buy button goes |
Why an array?
Section titled “Why an array?”Because the number of tiers may change. Add a new object, and a new pricing card appears. Remove one, and the card disappears. The page adapts automatically.
This is the same “array looping” concept used on the homepage — see Home Data for the full pattern.
How plan.mdx Uses Both Files
Section titled “How plan.mdx Uses Both Files”The page src/content/docs/plan.mdx imports plan/data.json:
---import Data from '../../data/pricing/data.json';import { Picture } from 'astro:assets';---Then it renders the page in two halves:
Half 1 — Content from plan/data.json
Section titled “Half 1 — Content from plan/data.json”The top of the page uses Data.image, Data.intro, Data.description:
<div class="col-md-10 mx-auto text-center p-3"> <Picture src={Data.image} alt={Data.description} ... /> <h2 class="small">{Data.description}</h2> <h3 class="fw-bold mt-3 mb-3">{Data.intro}</h3></div>Then two CTA blocks — “Buy Template” and “Hire”:
<div class="col-md-5 p-3 p-md-5"> <h3><strong><a href={Astro.url}>{Data.themes}</a></strong></h3> <p>{Data.themes_text}</p> <p><a href={Data.themes_link} class="btn btn-primary rounder">{Data.themes_button}</a></p></div><div class="col-md-5 p-3 p-md-5"> <h3><strong><a href={Astro.url}>{Data.hire}</a></strong></h3> <p>{Data.hire_text}</p> <p><a href={Data.hire_link} class="btn btn-primary rounder">{Data.hire_button}</a></p></div>Half 2 — Price list from pricing/pricing.json
Section titled “Half 2 — Price list from pricing/pricing.json”The price list itself is rendered by a widget that reads pricing/pricing.json. The MDX page simply imports and places it:
import Pricing from '../../widget/Pricing.astro';
<Pricing />The Pricing.astro widget then loops through resources:
---import Pricing from '../../data/pricing/pricing.json';---<div class="row"> {Pricing.resources.map(({ title, text, price, link }) => ( <div class="col-md-3 p-3"> <div class="card h-100"> <div class="card-body"> <h3>{title}</h3> <p>{text}</p> <h4 class="fw-bold">{price}</h4> <a href={link} class="btn btn-primary">Buy Now</a> </div> </div> </div> ))}</div>Each object in resources becomes one pricing card.
Full Data Flow
Section titled “Full Data Flow”src/data/pricing/data.json src/data/pricing/pricing.json │ │ ▼ ▼src/content/docs/plan.mdx src/widget/Pricing.astro (imports data.json directly) (imports pricing.json) │ │ └──────────────┬─────────────────────┘ ▼ /pricing/ pageTwo files, one page. The MDX handles layout and copy; the widget handles the repeating tier list.
Editing Workflow
Section titled “Editing Workflow”Scenario 1 — Change the hero headline
Section titled “Scenario 1 — Change the hero headline”- Open
src/data/pricing/data.json. - Find
"intro". - Change the value, save.
Scenario 2 — Update the Fiverr hire link
Section titled “Scenario 2 — Update the Fiverr hire link”- Open
src/data/pricing/data.json. - Find
"hire_link". - Replace the URL, save.
Scenario 3 — Add a new pricing tier
Section titled “Scenario 3 — Add a new pricing tier”- Open
src/data/pricing/pricing.json. - Add a new object to the
resourcesarray:
{ "title": "Enterprise", "text": "Full custom development with SLA support.", "price": "$500+", "link": "https://example.com/contact"}- Save. A new card appears automatically.
Scenario 4 — Reorder the tiers
Section titled “Scenario 4 — Reorder the tiers”- Cut the object you want to move.
- Paste it in a different position within the array.
- Save. The cards re-render in the new order.
Scenario 5 — Remove a tier
Section titled “Scenario 5 — Remove a tier”- Delete the object from the array.
- Save.
Why Two Files Instead of One?
Section titled “Why Two Files Instead of One?”You might wonder why the pricing tiers are not simply merged into plan/data.json. Two reasons:
- Separation of concerns. Page copy and product data are different things. The copy changes when you rebrand; the tiers change when you adjust your offer.
- Reusability. The same
pricing.jsoncan be used on the homepage, a pricing modal, or a blog post without duplicating content. Theplan/data.jsonis specific to the/pricing/page.
This is the same reason the homepage uses a single home.json — because the homepage has no reusable sub-components. The plan page does.
Rules for Editing These Files
Section titled “Rules for Editing These Files”- Keep valid JSON. No trailing commas, no comments, double quotes only.
- Do not change key names unless you also update the widgets that read them.
- Keep tier shapes consistent — every object in
resourcesshould havetitle,text,price,link. - Use
/src/assets/...paths for images referenced indata.json. - Prices are strings, not numbers. Use
"$65", not65. This allows"Custom"as a value.
Quick Recap
Section titled “Quick Recap”plan/data.json → page copy, hero, CTA blockspricing/pricing.json → array of pricing tiers │ │ └────────┬───────────────┘ ▼ plan.mdx page ▼ /pricing/ URL- Two files, one page. Content and price list are separate.
- plan/data.json is read directly inside
plan.mdx. - pricing/pricing.json is read by a
Pricing.astrowidget and looped. - Add a tier by adding one object to
resources. - Change copy by editing one string in
data.json.
👉 Next: docs/data/index-page.md — how JSON powers documentation landing pages.