Components
Nocturne is built on React. Every visible section is a component.
This page shows you where components live and how to edit them.
File Structure
src/components/
├── Home/
│ ├── Hero.tsx
│ ├── Video.tsx
│ ├── Features.tsx
│ ├── Testimonials.tsx
│ ├── Pricing.tsx
│ ├── BlogTeaser.tsx
│ └── CTA.tsx
├── Blog/
│ ├── BlogList.tsx
│ └── BlogPost.tsx
├── Navbar/
│ └── Navbar.tsx
└── Footer/
└── Footer.tsx
The Golden Rule
Components read from JSON files. Don't hardcode content in components.
Wrong:
<h1>Documentation that feels premium.</h1>
Right:
<h1>{homeData.hero.title}</h1>
This is why Decap CMS works — it edits the JSON, not the component.
Homepage Components
Every homepage section is a component that reads from src/data/home.json.
Hero
src/components/Home/Hero.tsx
Reads:
{
"hero": {
"badge": "NEW — NOCTURNE v1.0",
"title": "Documentation<br />that feels<br /><i>premium.</i>",
"sub": "Nocturne is a Docusaurus documentation system...",
"actions": [ ... ],
"trust": { ... },
"images": { ... }
}
}
To change hero content: edit home.json, not Hero.tsx.
To change hero layout: edit Hero.tsx.
Video
src/components/Home/Video.tsx
Reads:
{
"video": {
"badge": "LIVE DEMO • NOCTURNE",
"title": "See Nocturne<br />in action.",
"iframe": { ... },
"bar": { ... }
}
}
Features
src/components/Home/Features.tsx
Reads the features.cards array. Each card has type (large or small), title, text, and optionally image.
Testimonials
src/components/Home/Testimonials.tsx
Reads testimonials.list. Each item has name, role, img, text.
Pricing
src/components/Home/Pricing.tsx
Reads pricing.plans. Each plan has name, audience, price, items, action, and optionally badge and featured.
CTA
src/components/Home/CTA.tsx
Reads cta. Final call-to-action on the homepage.
Editing a Component
Example — change the hero layout:
Open src/components/Home/Hero.tsx.
Before:
<div className="hero-text-col">
<h1 dangerouslySetInnerHTML={{ __html: hero.title }} />
<p>{hero.sub}</p>
</div>
<div className="hero-visual-col">
<img src={hero.images.main.src} />
</div>
After — reverse the layout:
<div className="hero-visual-col">
<img src={hero.images.main.src} />
</div>
<div className="hero-text-col">
<h1 dangerouslySetInnerHTML={{ __html: hero.title }} />
<p>{hero.sub}</p>
</div>
Save. The dev server reloads. Hero is reversed.
Adding a New Section
Example — add a "Team" section to the homepage:
Step 1 — Add data to home.json:
"team": {
"badge": "● TEAM",
"title": "Built by a small team.",
"list": [
{ "name": "John Doe", "role": "Founder", "img": "/img/team/john.webp" }
]
}
Step 2 — Add fields to config.yml:
Under Home Content → fields:
- label: "Team"
name: "team"
widget: "object"
fields:
- { label: "Badge", name: "badge", widget: "string" }
- { label: "Title", name: "title", widget: "string" }
- label: "List"
name: "list"
widget: "list"
fields:
- { label: "Name", name: "name", widget: "string" }
- { label: "Role", name: "role", widget: "string" }
- { label: "Image", name: "img", widget: "image" }
Step 3 — Create the component:
src/components/Home/Team.tsx:
import React from 'react';
import homeData from '@site/src/data/home.json';
export default function Team() {
const { team } = homeData;
if (!team) return null;
return (
<section className="team-section">
<span className="badge">{team.badge}</span>
<h2>{team.title}</h2>
<div className="team-grid">
{team.list.map((member, i) => (
<div key={i} className="team-card">
<img src={member.img} alt={member.name} />
<h3>{member.name}</h3>
<p>{member.role}</p>
</div>
))}
</div>
</section>
);
}
Step 4 — Import in the homepage:
In src/pages/index.tsx:
import Team from '@site/src/components/Home/Team';
// ...
<Hero />
<Video />
<Features />
<Testimonials />
<Team /> {/* ← new section */}
<Pricing />
<BlogTeaser />
<CTA />
Step 5 — Restart the dev server:
npm start
The Team section appears on the homepage.
Editing Navbar
src/components/Navbar/Navbar.tsx or Docusaurus's built-in navbar.
Nocturne uses Docusaurus's navbar with custom CSS. To edit:
Content: src/data/navbar.json
Layout: src/css/nocturne.css (search for .navbar)
Advanced: src/theme/Navbar/ (if you've swizzled it)
Editing Footer
Content lives in src/data/navbar.json under footer.
Layout lives in src/components/Footer/Footer.tsx (or Docusaurus's default footer).
Swizzling Docusaurus Components
If you need to change a Docusaurus core component (navbar, sidebar, TOC), you can swizzle it:
npm run swizzle @docusaurus/theme-classic Navbar -- --wrap
This creates a wrapper in src/theme/. Edit it there.
Warning: Swizzling is advanced. Only do it if CSS doesn't work.
Best Practices
- Read from JSON, not hardcoded strings
- Keep components small — one section per component
- Use TypeScript types — define your data shape
- Test dark and light mode
- Test mobile and desktop
Troubleshooting
Component doesn't render
- Check that it's imported in
src/pages/index.tsx - Check the console for errors
- Check that the data exists in
home.json
Data doesn't show
- Check the JSON syntax
- Check the field name matches the component
- Check the browser console
CSS doesn't apply
- Check the class name
- Check that
nocturne.cssimports the component styles - Refresh with
Ctrl + Shift + R
TypeScript error
- Define the type for your data
- Use
anyas a temporary escape hatch - Check the Docusaurus docs
What's Next?
Now let's work with CSS.