Layouts and elements
components/elements/ is a convention for organizing your own components, not
an automatically detected directory. A component there only appears when imported
and rendered. Keep styles beside the component they belong to.
Override files and fallback
Each override is optional and independent:
Use
.jsx or .tsx with a default export. Do not create both extensions for the
same override. Older flat paths such as components/Header.jsx still work;
components/layouts/Header.jsx takes precedence when both exist. Remove both
versions to restore the built-in header. Other regions keep their own defaults.
A broken override reports an error; it does not silently fall back. Returning
null intentionally hides that region. Omitting a TOC or pagination from a custom
layout also leaves it out; Lettercamp does not insert missing controls.
Try the starter examples
The bundled starter includesexamples/layouts/. These examples use the same elements and default
styles as the built-in site. They are inactive until copied into
components/layouts/.
Copy only the layout you want to edit:
Keep a default element
The publicHeader, Footer, and PostCard always render Lettercamp’s default
element. Import one with an alias to distinguish it from your override:
Post list
A custom list owns its heading, navigation, cards, empty state, and pagination. Use the suppliedPostCard to honor your card override and its default fallback:
An imported
PostCard from lettercamp/components always uses the standard card.
The PostCard prop uses your override when present. Choose the prop when you want
your card design to apply throughout the publication.
Post card
Start with the standard card:post. The card receives site, pathname,
basePath, and priority in addition to post. Set eager image loading when
priority is true. Search results use their own presentation.
Post layout
The starter composes the standard article header, TOC, article body, and related posts. Add your own component directly where you want it, for example immediately after{children}:
PostHeader includes the title, description, category, cover, byline, and sharing.
TableOfContents defaults to the floating control on the left. The starter
explicitly selects sidebar for the horizontal article layout.
Render children once. Lettercamp supplies the rendered body and its built-in
block styles. Keep article content in pages/; do not parse Markdown in the layout
or copy article text into React code.
Shared props and post data
All five overrides receive:
A
post includes the article’s frontmatter plus these normalized fields:
Use supplied URLs directly. Do not prepend
basePath again to post links,
images, category links, or pagination URLs. Use basePath when creating your own
publication-relative navigation. Absolute URLs can link to the parent website.
Components render during the build and hydrate in the browser. Use browser APIs
such as window inside effects or event handlers, not during rendering. Keep
these components compatible with browser execution for online previews.
Settings and defaults
Pass the layout’ssite to settings-aware components so they use live settings
in the editor preview. PostHeader honors hero layout, cover visibility, reading
width, and reading-time visibility. TableOfContents and RelatedPosts honor
their visibility settings. The default header and footer honor their settings.
Your own markup only follows settings you use in code. The starter layouts show
how to retain reading width, listing layout, and the standard components. You can
intentionally replace those choices with your own design.
The online design customizer identifies custom layouts and replaces the built-in
layout picker for a custom list or article. Other controls apply where your
components use them. Removing an override restores the saved default settings.
Colors and typography remain available through CSS variables. Site identity,
favicon, language, time zone, SEO, and analytics remain managed by Lettercamp.
Write a component
Create ordinary components undercomponents/elements/ and import them from your
layout using a relative path, such as ../elements/NewsletterSignup.jsx. See
React components for authoring and
supported imports for Cloud dependencies.
Add styles with CSS Modules
Createcomponents/layouts/Header.module.css beside your component:
className={styles.header}. Lettercamp bundles the
CSS with unique class names. Site typography and global element styles still apply.
Use variables such as var(--font-family) and var(--site-background) to match
your publication. Local previews and standalone builds support assets in
public/; see Cloud asset preparation
when publishing to Lettercamp.
Style your post components
Keep each stylesheet beside its component and import it:- Standard elements:
h2,p,a,ul,blockquote, and other Markdown output. - Body root:
[data-lettercamp-body]. - Rich blocks:
[data-lettercamp-table],[data-lettercamp-code],[data-lettercamp-faq],[data-lettercamp-key-takeaways], and[data-lettercamp-subscribe]. - Width choices:
data-block-width,data-image-width,data-table-width, anddata-code-width, with values such asregular,wide, andfull. - Shared variables:
--font-family,--heading-font,--site-background,--site-foreground,--site-border, and--post-content-width.
overflow: hidden. Avoid depending on generated CSS Module
class names. A custom stylesheet can still hide or distort content, so check
representative tables, media, code, and FAQs at desktop and mobile widths.
Keep article typography separate from block UI
CSS Modules make class names local; they do not isolate descendant elements. A rule such as.content h2 also matches an email subscribe title inside that
wrapper. Use .content :global(.prose > h2) for top-level article headings,
and give your own post header a separate module class. Use explicit selectors
for nested article content, such as .content :global(.prose blockquote > p).
Lettercamp’s subscribe title, description, and status message define their own
spacing inside .prose, so ordinary article typography does not add heading
dividers or paragraph margins to them. They still inherit your site’s fonts and
colors. This is CSS scoping, not a Shadow DOM boundary: highly specific selectors
and !important can still override native styles.
To intentionally customize a subscribe block, target its parts instead of all
headings or paragraphs:
[data-subscribe-card], [data-subscribe-title],
[data-subscribe-description], [data-subscribe-form],
[data-subscribe-button], and [data-subscribe-message]. Preserve form controls,
focus styles, and status messages. Check the rendered Preview as well as the
rich text editor, which uses its own editing styles.
Use the web editor
Article content stays editable through either the Markdown/MDX files or the online rich editor. Write uses Lettercamp’s editing surface; Preview shows the custom post components from the last successful build with current draft content and settings. New and unpublished articles can use that layout too. The site build bundles the post components and their CSS once. Editing text, a table, metadata, or settings updates preview data without compiling the theme again. Publish component or stylesheet changes to update the online theme bundle; locallettercamp dev updates while you work on those files. No per-editor
server is required. Keep generated assets with the site when self-hosting.
Built-in rich blocks render in the draft preview. Arbitrary React imports and
JavaScript expressions inside an MDX article remain placeholders in the online
editor and draft preview; inspect those with lettercamp dev or a published page.
Custom headers and footers retain their existing online preview placeholders.
Preview and publish
Runnpx lettercamp dev for live updates as you edit code and CSS or add and remove
layout components.
Run npx lettercamp check before publishing. Agents should use
npx lettercamp check --json and fix the reported problems until the full build
passes. This catches dependencies and aliases that can work in a local preview
but fail on Cloud. Use local icon components with inline SVG instead of installing
an icon library.
Publish your component files and stylesheets with npx lettercamp deploy, or
commit them to the repository connected to GitHub publishing.
For self-hosting, run npx lettercamp build --site https://example.com and upload the
entire output directory, including its generated CSS and JavaScript assets.