Content Editing
Pulse AI uses a content-driven architecture, which means most page content is stored inside dedicated content files rather than directly inside components.
This makes it easy for content editors, marketers, and developers to update copy, images, features, pricing, legal pages, and blog content without touching UI code.
Content Directory Structure
All editable content is located inside the content directory.
pulse-ai/
├── content/
│ ├── blog/
│ ├── marketing/
│ ├── legal/
│ └── shared/Folder Purpose
| Folder | Description |
| ----------- | ----------- |
| blog | Blog posts, articles, guides, and resources |
| marketing | Homepage, landing pages, pricing, features, testimonials, FAQs, etc. |
| legal | Privacy Policy, Terms of Service, Cookie Policy, Compliance pages |
| shared | Reusable content used across multiple pages |
How Content Is Imported
Components do not contain hardcoded text. Instead, content is imported from the content directory.
import { BENEFITS_CONTENT } from "@/content/marketing/benefits";The imported content is then passed into a component:
<BenefitsSection
title={BENEFITS_CONTENT.title}
subtitle={BENEFITS_CONTENT.subtitle}
benefits={BENEFITS_CONTENT.items}
/>This means you only need to edit the content file when updating website copy.
Example Content File
File location:
content/
└── marketing/
└── benefits.ts
Content:
export const BENEFITS_CONTENT = {
title: "Why Teams Choose Pulse AI",
subtitle: "Automate workflows, improve productivity, and scale faster.",
items: [
{
title: "Save Time",
description: "Automate repetitive tasks and focus on strategic work.",
icon: "Clock",
},
{
title: "Increase Revenue",
description: "Generate more leads and improve conversion rates.",
icon: "TrendingUp",
},
{
title: "Improve Collaboration",
description: "Keep your team aligned with centralized workflows.",
icon: "Users",
},
],
};Matching Component Props
Content objects should mirror the structure expected by the component.
For example, if a component expects:
interface BenefitItem {
title: string;
description: string;
icon: LucideIcon;
}
interface BenefitsSectionProps {
title: string;
subtitle: string;
benefits: BenefitItem[];
}The content file should provide matching data:
export const BENEFITS_CONTENT = {
title: "Why Teams Choose Pulse AI",
subtitle: "Automate workflows, improve productivity, and scale faster.",
items: [
{
title: "Save Time",
description: "Automate repetitive tasks.",
icon: Clock,
},
],
};Then map it into the component:
<BenefitsSection
title={BENEFITS_CONTENT.title}
subtitle={BENEFITS_CONTENT.subtitle}
benefits={BENEFITS_CONTENT.items}
/>Because the data shape matches the component props, the component renders content automatically without additional changes.
Recommended Content Pattern
For maximum flexibility, export content as plain objects.
export const HERO_CONTENT = {
badge: "Trusted by 5,000+ Teams",
title: "Scale Faster With AI",
subtitle: "Automate operations and increase productivity.",
primaryButton: {
label: "Get Started",
href: "/signup",
},
secondaryButton: {
label: "Book Demo",
href: "/demo",
},
image: "/images/hero/dashboard.webp",
};Component Usage Example
Content file:
export const HERO_CONTENT = {
title: "Scale Faster With AI",
subtitle: "Automate operations and increase productivity.",
};Component:
interface HeroProps {
title: string;
subtitle: string;
}
export default function Hero({ title, subtitle }: HeroProps) {
return (
<section>
<h1>{title}</h1>
<p>{subtitle}</p>
</section>
);
}Page:
import Hero from "@/components/sections/hero";
import { HERO_CONTENT } from "@/content/marketing/hero";
export default function HomePage() {
return (
<Hero
title={HERO_CONTENT.title}
subtitle={HERO_CONTENT.subtitle}
/>
);
}Shared Content
Use the shared directory for content reused across multiple pages.
content/
└── shared/
└── company.ts
export const COMPANY = {
name: "Pulse AI",
email: "hello@pulseai.com",
supportEmail: "support@pulseai.com",
};Usage:
import { COMPANY } from "@/content/shared/company";
<footer>
Contact us at {COMPANY.email}
</footer>Hero Content
Hero content lives inside the marketing directory.
content/
└── marketing/
└── hero.ts
export const HERO_CONTENT = {
badge: "Trusted by 5,000+ Teams",
title: "Scale Faster With AI",
subtitle: "Automate operations and increase productivity.",
primaryButton: {
label: "Get Started",
href: "/signup",
},
secondaryButton: {
label: "Book Demo",
href: "/demo",
},
image: "/images/hero/dashboard.webp",
};Legal Content
Legal documents live inside the legal directory.
content/
└── legal/
├── privacy-policy.ts
├── terms-of-service.ts
└── cookie-policy.ts
export const PRIVACY_POLICY = {
title: "Privacy Policy",
sections: [
{
heading: "Information We Collect",
content: "We collect information you provide directly to us.",
},
],
};Best Practices
- Keep all editable text inside
content/ - Match content structure to component props
- Use descriptive export names
- Store reusable values in
shared/ - Avoid hardcoded marketing copy inside components
- Keep components focused on presentation and layout
- Let content files control text, images, links, and CTA labels
Summary
Pulse AI separates content from presentation. Components are responsible for how content looks, while files inside the content directory control what content is displayed.
This approach makes the application easier to maintain, easier to localize, and significantly faster to update without modifying component logic.