Skip to main content

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)


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​

  1. Check that it's imported in src/pages/index.tsx
  2. Check the console for errors
  3. Check that the data exists in home.json

Data doesn't show​

  1. Check the JSON syntax
  2. Check the field name matches the component
  3. Check the browser console

CSS doesn't apply​

  1. Check the class name
  2. Check that nocturne.css imports the component styles
  3. Refresh with Ctrl + Shift + R

TypeScript error​

  1. Define the type for your data
  2. Use any as a temporary escape hatch
  3. Check the Docusaurus docs

What's Next?​

Now let's work with CSS.

👉 Next: CSS →