Skip to content

Home Data

src/data/home.json is the single source of truth for your landing page — the very first thing visitors see when they open your site.

Every headline, button, feature card, service step, hosting logo, and footer image on the homepage comes from this one file. Nothing on the landing page is hardcoded inside a component.

If you want to change the hero text, add a new feature, reorder the deploy options, or update the pricing button — you edit home.json. That’s it.


src/data/
└── home.json

It sits at the top level of the data/ folder because it does not belong to any subcategory. It is the primary dataset of the entire site.


The landing page is not one big block. It is built from multiple sections, stacked one after another:

Header (hero) ← title, description, buttons, hero image
Intro ← "What this template offers" cards
Features ← "Built with Astro & Starlight" cards
Services ← "How it works" step cards
Resources ← "Documentation Guides" cards
Tech ← "Deploy Anywhere" hosting logos
Help ← "Need help with setup?" call-to-action
Footer ← footer image

Each section has its own set of keys inside home.json. For example:

  • The header section uses title, description, button, button_link, image.
  • The intro section uses intro_title, intro_text, and an intro array.
  • The features section uses features_title, features_text, and a features array.

This means the file is structured like a book with chapters, and each widget only reads the chapter it needs.


Here is a bird’s-eye view of every section in home.json:

KeyTypePowers
urlstringCanonical URL used in metadata
titlestringHero headline + page title
descriptionstringHero subtitle + SEO description
bannerstringSocial preview image
banner1stringSecondary banner image
iconstringSite icon
imagestringHero image
button / button_linkstringPrimary hero CTA
button1 / button1_linkstringSecondary hero CTA
intro_title / intro_textstringIntro section heading
introarrayIntro section cards
features_title / features_textstringFeatures section heading
featuresarrayFeatures section cards
services_title / services_textstringServices section heading
servicesarrayServices step cards
resources_title / resources_textstringResources section heading
resourcesarrayResources cards
tech_title / tech_textstringTech section heading
techarrayTech / hosting logos
help_title / help_textstringHelp CTA heading
help_button / help_linkstringHelp CTA button
footer_imagestringFooter logo / illustration

Notice the pattern: every section has a title, an optional text, and often an array of items. That consistency makes the data predictable and easy to edit.


Each landing page section is a widget in src/widget/. Let’s look at the header widget as a real example.

---
import Data from '../data/home.json';
import { Picture } from 'astro:assets';
---
<header class="container-fluid">
<div class="row">
<div class="col-md-7 p-3 p-md-5">
<div class="p-3">
<h2 class="fw-bold h1">{Data.title}</h2>
<h3 class="mb-4 mt-3 h5">{Data.description}</h3>
<p>
<a href={Data.button_link} class="btn logor cordas">{Data.button}</a>
<a href={Data.button1_link} class="ms-3 btn logor cordas" target="_blank">{Data.button1}</a>
</p>
</div>
</div>
<div class="col-md-5">
<Picture
src={Data.image}
alt={Data.title}
formats={['avif', 'webp']}
sizes={`(max-width: 360px) 240px, (max-width: 720px) 540px, (max-width: 1600px) 720px`}
width="400"
height="200"
class="img-fluid"
decoding="async"
/>
</div>
</div>
</header>
  1. Import — the widget loads home.json into a variable called Data.
  2. Direct access — because this section only needs the hero fields, it reads Data.title, Data.description, Data.image, etc. directly.
  3. Buttons — the two CTA buttons pull their text and destination from Data.button, Data.button_link, Data.button1, Data.button1_link.
  4. Image — Data.image is the hero image, passed into Astro’s <Picture /> component for optimization.

No text is written inside the widget. Everything is external.


Some sections loop through arrays. For example, the intro section:

"intro": [
{
"title": "Documentation Ready",
"image": "/src/assets/fg.svg",
"text": "Starlight setup with sidebar autogenerate..."
},
{
"title": "Blog with Tags & Categories",
"image": "/src/assets/ds.svg",
"text": "Blog system with pagination, tags, categories and RSS..."
}
]

A widget would render this with a .map() loop:

{Data.intro.map(({ title, image, text }) => (
<div class="card">
<img src={image} alt={title} />
<h3>{title}</h3>
<p>{text}</p>
</div>
))}

To add a new intro card: add one more object to the array. The widget automatically renders it. No code changes needed.

This is the same pattern used for:

  • intro
  • features
  • services
  • resources
  • tech

All five arrays behave identically from a coding perspective.


In a typical Astro Docus setup, the landing page (src/content/docs/index.mdx or a custom homepage) imports each widget in order:

import Header from '../../widget/Header.astro';
import Intro from '../../widget/Intro.astro';
import Features from '../../widget/Features.astro';
import Services from '../../widget/Services.astro';
import Resource from '../../widget/Resource.astro';
import Tech from '../../widget/Tech.astro';
import Help from '../../widget/Help.astro';
<Header />
<Intro />
<Features />
<Services />
<Resource />
<Tech />
<Help />

Each widget reads only the slice of home.json it needs. The file is shared across all of them.


  1. Open src/data/home.json.
  2. Find the "title" key at the top.
  3. Replace the value.
  4. Save. The change appears on the homepage immediately in dev mode.
  1. Open src/data/home.json.
  2. Find the "features" array.
  3. Add a new object:
{
"title": "New Feature",
"image": "/src/assets/seo.svg",
"text": "Description of the new feature here."
}
  1. Save. The features section now shows one more card.
  1. Find "button1" and "button1_link".
  2. Change the text and the URL.
  3. Save.
  1. Place your new image in src/assets/.
  2. Update "image" to point to the new file:
"image": "/src/assets/my-new-hero.png"
  1. Save.

  1. Keep valid JSON. No trailing commas, no comments, double quotes only.
  2. Do not rename keys unless you also update the widget that reads them.
  3. Keep array item shapes consistent. If one intro item has title, image, text, all items should have the same keys.
  4. Use absolute paths from the project root for images: /src/assets/....
  5. Check the widget before adding new keys — a key that no widget reads will do nothing.

Imagine you had to change the hero headline on a traditional static site. You would:

  • Open index.html
  • Find the hero section
  • Edit the text
  • Save
  • Push to production

Now imagine you want to change it in three languages or three campaigns. You would duplicate the HTML three times.

With home.json, you change one string. If you later add a second homepage variant, you can point it to a different JSON file and reuse the same widgets.

This is the heart of the Astro Docus philosophy: data first, code second.


src/data/home.json
├── title, description, image, buttons → Header widget
├── intro_title, intro_text, intro[] → Intro widget
├── features_title, features[], ... → Features widget
├── services_title, services[], ... → Services widget
├── resources_title, resources[], ... → Resource widget
├── tech_title, tech[], ... → Tech widget
├── help_title, help_button, help_link → Help widget
└── footer_image → Footer
  • One file powers the entire landing page.
  • Each widget reads only its slice of the data.
  • Arrays drive looping sections — add an item, get a card.
  • No hardcoding — every text and image lives in JSON.

👉 Information about data: docs/data/home-index.mdx — deep dive into the intro section.