Docs Index Page
What Is This?
Section titled “What Is This?”Once you finish writing your documentation, you may want to make your index pages (the landing page of each docs folder) more visually appealing.
Instead of a plain list of links, you can render a grid of cards, each with an icon, a title, a short description, and a link.
This is entirely optional. If your docs work fine without it, you can skip this page entirely. But if you want a polished, professional look for folders like /getstart/, /cms/, or /deploy-hosting/, this is how to do it.
The Concept
Section titled “The Concept”The pattern is the same as everywhere else in Astro Docus:
JSON file → index.mdx → card gridYou create one JSON file per docs folder, name it to match the folder, and then render it inside that folder’s index.mdx.
| Docs folder | JSON file |
|---|---|
src/content/docs/getstart/ | src/data/index_page/getstart.json |
src/content/docs/cms/ | src/data/index_page/cms.json |
src/content/docs/deploy-hosting/ | src/data/index_page/hosting.json |
src/content/docs/services/ | src/data/index_page/services.json |
The name must match. If your docs folder is getstart, your JSON file must be getstart.json.
Step 1 — Create the JSON File
Section titled “Step 1 — Create the JSON File”Inside src/data/index_page/, create a new file named after your docs folder.
Example — src/data/index_page/getstart.json:
{ "resources": [ { "title": "Download Source", "image": "/src/assets/download.svg", "text": "Get source code from Gumroad after purchase. Unlimited sites.", "link": "/getstart/download/" }, { "title": "Installation", "image": "/src/assets/ins.svg", "text": "Run npm install and npm run dev. Works on localhost:4321.", "link": "/getstart/installation/" }, { "title": "Configuration", "image": "/src/assets/cof.svg", "text": "Edit astro.config.mjs for title, logo and sidebar.", "link": "/getstart/configuration/" } ]}Structure rules
Section titled “Structure rules”| Field | Purpose |
|---|---|
resources | The array name — must be exactly resources |
title | Card title, also used as image alt text |
image | Path to the icon or image (/src/assets/...) |
text | Short description shown under the title |
link | Where the card links to |
Every object in the array must have all four keys. Missing keys cause the card to render incorrectly.
Choosing images
Section titled “Choosing images”Use small SVG icons from src/assets/ for best results. Recommended size: 80×80 pixels.
Common icons available in the template:
download.svgins.svg(installation)cof.svg(configuration)data.svgdeploy.svgarticle.svgblo.svg(blog)wd.svg(widget)gits.svg(GitHub)hiost.svg(hosting)
You can also add your own icons to src/assets/ and reference them.
Step 2 — Update the Index Page
Section titled “Step 2 — Update the Index Page”Open the index.mdx for the folder you want to enhance. For example, src/content/docs/getstart/index.mdx.
Replace its content with:
---title: Get Startdescription: Get Started with Astro Docus templatetableOfContents: falsenext: false---import Data from '../../../data/index_page/getstart.json';import '../../../styles/index_page.css';import { Picture } from 'astro:assets';
<div class="grid-container"> { Data.resources.map(({ title, image, text, link }) => ( <div class="grid-item"> <a href={link}> <Picture src={image} alt={title} formats={['avif', 'webp']} width="80" height="80" class="img-fluid" decoding="async" /> </a>
<h3><a href={link}>{title}</a></h3> <p>{text}</p> </div> ))}</div>What each line does
Section titled “What each line does”Frontmatter:
title: Get Startdescription: Get Started with Astro Docus templatetableOfContents: falsenext: falsetitle— page titledescription— meta descriptiontableOfContents: false— hide the right-side TOC (card grids don’t need it)next: false— hide the “Next page” link at the bottom
Imports:
import Data from '../../../data/index_page/getstart.json';import '../../../styles/index_page.css';import { Picture } from 'astro:assets';Data— the JSON file you createdindex_page.css— the stylesheet that styles the gridPicture— Astro’s image optimization component
The grid:
<div class="grid-container"> { Data.resources.map(({ title, image, text, link }) => ( ... ))}</div>.grid-container— a CSS grid defined inindex_page.cssData.resources.map(...)— loops through every card{ title, image, text, link }— destructures each card’s fields- Each card renders as
<div class="grid-item">
Step 3 — Verify the CSS Is Loaded
Section titled “Step 3 — Verify the CSS Is Loaded”The card grid relies on classes defined in src/styles/index_page.css:
.grid-container— the outer grid.grid-item— each individual card
If the cards look unstyled (all stacked vertically, no spacing), the CSS import is missing. Make sure this line is present:
import '../../../styles/index_page.css';You can also add your own styles by editing src/styles/index_page.css.
The CSS Behind the Grid
Section titled “The CSS Behind the Grid”For reference, index_page.css typically contains something like:
.grid-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.5rem; margin: 2rem 0;}
.grid-item { padding: 1.5rem; border: 1px solid var(--bs-border-color); border-radius: 12px; transition: transform 0.2s ease, box-shadow 0.2s ease;}
.grid-item:hover { transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);}
.grid-item h3 { font-size: 1.1rem; margin-top: 1rem;}
.grid-item p { font-size: 0.95rem; opacity: 0.8;}You can adjust minmax(220px, 1fr) to control how many cards fit per row. For example:
minmax(180px, 1fr)→ more, smaller cards per rowminmax(280px, 1fr)→ fewer, larger cards
Full Example — /getstart/
Section titled “Full Example — /getstart/”File: src/data/index_page/getstart.json
Section titled “File: src/data/index_page/getstart.json”{ "resources": [ { "title": "Download", "image": "/src/assets/download.svg", "text": "Get the source code from Gumroad after purchase.", "link": "/getstart/download/" }, { "title": "Installation", "image": "/src/assets/ins.svg", "text": "Install dependencies and run locally on port 4321.", "link": "/getstart/installation/" }, { "title": "Configuration", "image": "/src/assets/cof.svg", "text": "Edit astro.config.mjs for title, logo and sidebar.", "link": "/getstart/configuration/" }, { "title": "Folder Structure", "image": "/src/assets/geal.svg", "text": "Overview of src, data, content and pages folders.", "link": "/getstart/structure/" } ]}File: src/content/docs/getstart/index.mdx
Section titled “File: src/content/docs/getstart/index.mdx”---title: Get Startdescription: Get Started with Astro Docus templatetableOfContents: falsenext: false---import Data from '../../../data/index_page/getstart.json';import '../../../styles/index_page.css';import { Picture } from 'astro:assets';
## {frontmatter.description}
<div class="grid-container"> { Data.resources.map(({ title, image, text, link }) => ( <div class="grid-item"> <a href={link}> <Picture src={image} alt={title} formats={['avif', 'webp']} width="80" height="80" class="img-fluid" decoding="async" /> </a>
<h3><a href={link}>{title}</a></h3> <p>{text}</p> </div> ))}</div>Result: /getstart/ shows a grid of four cards.
Adding and Removing Cards
Section titled “Adding and Removing Cards”Add a card
Section titled “Add a card”- Open your JSON file.
- Add a new object to the
resourcesarray with all four fields. - Save.
Remove a card
Section titled “Remove a card”- Delete the object from the array.
- Save.
Reorder cards
Section titled “Reorder cards”- Cut and paste objects within the array.
- Save. The order in the array is the order on the page.
Reusing One JSON File for Multiple Folders
Section titled “Reusing One JSON File for Multiple Folders”You can point multiple index.mdx files at the same JSON file if you want identical card layouts:
import Data from '../../../data/index_page/getstart.json';Just change the path. This is useful for template examples or shared content.
However, the convention in Astro Docus is one JSON file per folder, named after the folder. This keeps things predictable.
When to Use This
Section titled “When to Use This”Use index page cards when:
- Your docs folder has multiple sub-pages and you want a visual overview.
- You want the index to feel like a hub rather than a list.
- You have icons for each sub-page.
Skip this when:
- The folder has only one or two pages.
- Your docs are linear and best shown as a list.
- You don’t have matching icons.
Rules to Remember
Section titled “Rules to Remember”- JSON filename must match the docs folder name.
getstart/→getstart.json. - The array must be named
resources. Themap()call depends on it. - Every card needs all four keys —
title,image,text,link. - Use
/src/assets/...paths for images so Astro can optimize them. - Import the CSS — without
index_page.css, the grid looks broken. - Set
tableOfContents: falseandnext: falsein frontmatter for a cleaner index.
Quick Recap
Section titled “Quick Recap”src/data/index_page/getstart.json │ ▼src/content/docs/getstart/index.mdx │ ▼ /getstart/ → grid of cardsThree steps:
- Create
src/data/index_page/<folder>.jsonwith aresourcesarray. - Import it in
src/content/docs/<folder>/index.mdx. - Loop with
.map()inside a.grid-container.
Optional but powerful. When applied consistently, every docs folder becomes a polished, navigable hub.