Codapult includes two content systems — a blog and a help center — both powered by MDX files on disk. No CMS or database required; just write Markdown with optional JSX components.
After purchase, replace the Codapult marketing content with your own product's content before shipping your SaaS. The default files are real Codapult sales material, not neutral placeholder copy.
Replacing the Marketing Content
The public marketing site lives under src/app/[locale]/(marketing)/. Its reusable sections live in src/components/marketing/, and most default copy/data comes from config, messages, and MDX content.
Treat the shipped marketing surface as a reference implementation, not as reusable neutral copy. It describes Codapult, its pricing, its plugin catalog, and its competitors. Keeping it unchanged in your own SaaS will create incorrect SEO pages, product claims, legal copy, and checkout paths.
Use this checklist when turning the template into your own product:
| Area | Replace or review |
|---|---|
| Landing page sections | src/app/[locale]/(marketing)/page.tsx, src/components/marketing/* |
| Landing page copy, stats, testimonials, module cards | src/config/marketing.ts |
| Pricing tiers, plugin cards, checkout product keys | src/config/marketing-pricing.ts |
| Competitor comparison pages | src/config/competitor-comparison.ts, src/app/[locale]/(marketing)/compare/ |
| Blog posts and RSS feed content | content/blog/ |
| Help center documentation | content/docs/ |
| Navbar, footer, page UI copy, locale strings | messages/*.json |
| Brand name, logo, footer badge, support links | src/config/app.ts, public/logo.svg, public/logo-letter.svg |
| Legal pages | src/app/[locale]/(marketing)/privacy/page.tsx, src/app/[locale]/(marketing)/terms/page.tsx |
If you keep the blog or help center enabled, delete Codapult-specific files and add your own. If you do not need them yet, disable the public routes with ENABLE_BLOG=false or ENABLE_HELP_CENTER=false and remove the links from your navigation copy.
The default docs explain Codapult to developer-buyers. For your own SaaS, rewrite content/docs/ for your product's users, admins, API consumers, or internal support team. The default blog targets developers evaluating SaaS boilerplates; replace it with posts that match your product's audience and search intent.
Recommended replacement order:
- Update
src/config/app.tsand logo/icon assets first so metadata, emails, and legal pages use your brand. - Rewrite
messages/en.jsonmarketing namespaces (Hero,ProductPricing,FAQ,Nav,Footer) and repeat for any enabled locales. - Replace
src/config/marketing.ts,src/config/marketing-pricing.ts, andsrc/config/competitor-comparison.tswith product-specific data. - Rewrite or disable
content/blog/andcontent/docs/before indexing the production domain. - Review
sitemap.ts,robots.ts, Open Graph images, RSS, privacy, and terms pages for any remaining Codapult-specific claims.
MDX Blog
File Location
Blog posts live in content/blog/ as .mdx files.
Frontmatter
Every post starts with YAML frontmatter:
---
title: Launching Our API v2
description: A faster, more reliable API with breaking change migration guide.
date: 2026-03-15
author: Jane Doe
tags: [api, release]
image: /images/blog/api-v2.png
published: true
---
Your markdown content here...
| Field | Required | Description |
|---|---|---|
title | Yes | Post title |
description | Yes | Short summary for SEO and listing cards |
date | Yes | Publication date (YYYY-MM-DD) |
author | Yes | Author name |
tags | No | Array of tags for filtering |
image | No | Cover image path |
published | No | Set to false to hide from listings |
canonical_url | No | Absolute canonical URL for cross-posting to dev.to or similar platforms |
devto_tags | No | Optional dev.to tag list used by publishing workflow docs |
Internationalization
Blog posts support per-locale translations using a filename convention:
| File | Locale |
|---|---|
my-post.mdx | Default (English) |
my-post.ru.mdx | Russian |
my-post.de.mdx | German |
my-post.fr.mdx | French |
my-post.ja.mdx | Japanese |
If a translation is unavailable for the current locale, the default-locale version is shown.
Utilities
The src/lib/blog/ module provides server-side functions:
| Function | Description |
|---|---|
getAllPosts(locale?) | List all published posts (newest first) |
getPostBySlug(slug, locale?) | Get a single post with full MDX content |
getAllTags(locale?) | Get all unique tags |
getPostsByTag(tag, locale?) | Filter posts by tag |
getPostsByAuthor(author, locale?) | Filter posts by author |
getAllAuthors(locale?) | List all authors with post counts |
getAllSlugs() | Get all post slugs (for static generation) |
Components
| Component | Description |
|---|---|
BlogSearch | Client-side search across post titles and descriptions |
TagCloud | Tag list with post counts, links to filtered views |
LocaleSwitch | Language switcher for translated posts |
MdxContent | Renders MDX content with custom component mappings |
RSS Feed
An RSS feed is automatically generated at /rss.xml from published blog posts.
Help Center / Documentation
File Location
Documentation articles live in content/docs/<category>/<slug>.mdx, organized into category folders.
Frontmatter
---
title: Getting Started
description: Install and configure the app in under 5 minutes.
category: getting-started
order: 1
published: true
---
Your documentation content here...
| Field | Required | Description |
|---|---|---|
title | Yes | Article title |
description | Yes | Short summary for SEO and navigation |
category | Yes | Folder name (e.g. getting-started, billing) |
order | Yes | Sort position within the category |
published | No | Set to false to hide from navigation |
Auto-Generated Navigation
The help center builds its sidebar navigation automatically from the file structure:
- Categories are derived from folder names
- Articles are sorted by
orderwithin each category - Category order is determined by the lowest
ordervalue among its articles
No configuration file is needed — add a folder and an MDX file, and it appears in the sidebar.
Full-Text Search
The searchDocs(query) function searches across article titles, descriptions, and content:
import { searchDocs } from '@/lib/docs';
const results = searchDocs('authentication');
// [{ title, description, category, slug, order, published }, ...]
The HelpDocSearch component provides a ready-made search UI with instant results.
Utilities
| Function | Description |
|---|---|
getDocCategories() | List all categories with their articles |
getDocArticle(category, slug) | Get a single article with MDX content |
getAllDocSlugs() | Get all { category, slug } pairs (for static generation) |
searchDocs(query) | Full-text search across all articles |
Adding Content
New Blog Post
Create a file in content/blog/:
touch content/blog/my-new-post.mdx
Add frontmatter and content. The post appears on the blog page after a dev server reload (or production rebuild).
New Documentation Article
Create a file in content/docs/<category>/:
mkdir -p content/docs/integrations
touch content/docs/integrations/webhooks.mdx
Add frontmatter with the category matching the folder name and an order value. The article appears in the help center sidebar automatically.
New Documentation Category
Simply create a new folder under content/docs/ and add at least one .mdx file. The category name in the sidebar is derived from the folder name (e.g. getting-started → "Getting Started").
MDX Components
Both blog and docs content is rendered with MdxContent, which provides standard Markdown elements plus GFM (tables, strikethrough, task lists) via remark-gfm. You can use:
- Headings (
# H1through#### H4) — auto-generate anchor links for the table of contents - Code blocks with syntax highlighting — use triple backticks with a language tag
- Tables — standard GitHub-flavored Markdown tables
- Images — reference files from
public/images/(e.g.) - Links — internal links use relative paths (e.g.
[Auth docs](/docs/authentication/overview))
To add custom JSX components to MDX, extend the components prop in the MdxContent usage within src/app/[locale]/(marketing)/docs/[category]/[slug]/page.tsx or the blog page.