This guide is for migrating an external theme (for example Astro/Vite themes) into NotionNext's Next.js + Notion data architecture.
- Keep the original theme's visual language (layout, spacing, cards, motion).
- Follow NotionNext's data flow and feature conventions.
- Expose behavior through
themes/<theme>/config.jsswitches instead of hardcoding.
Create a dedicated theme folder:
themes/<theme>/index.jsthemes/<theme>/style.jsthemes/<theme>/config.jsthemes/<theme>/components/*
Rules:
- Do not import UI components from other theme folders.
- Keep cross-theme shared components only from global
@/components/*when needed (for exampleNotionPage,Comment,ShareBar,FlipCard, ads widgets). - Keep theme-specific rendering and style under the theme folder.
Common props available in theme layouts/components:
siteInfo: site metadata, cover, title, descriptionposts,post,archivePostslatestPosts,categoryOptions,tagOptionsnoticepostCountprev,nextcustomNav,customMenurightAreaSlot
Typical post fields used by themes:
title,slug,href,summarypublishDay,lastEditedDaypageCover,pageCoverThumbnailcategory,tagItemstoc
When migrating a new theme, verify all of these:
-
Data-driven menu
- Support default menu items.
- Support
customNav. - Support
CUSTOM_MENUoverriding withcustomMenu.
-
Notice/announcement block
- Render Notion content using
NotionPage. - Switchable in theme config.
- Render Notion content using
-
Notion cover as Hero
- Use
siteInfo.pageCoveras first priority for home hero background. - Keep fallback image config.
- Use
-
Dark mode support
- Use global context (
useGlobal) andtoggleDarkMode. - Avoid isolated theme-only dark state.
- Use global context (
-
Article module compatibility
- TOC panel switch
- Share module switch
- Comment module switch
- Copyright block switch
- Adjacent posts switch
-
Sidebar modularity
- Latest posts, categories, tags
- Contact card (optional flip card)
- Analytics card
- Ads card
- Plugin slot (
rightAreaSlot)
-
Float tools
- Back to top
- Jump to comment
- Dark mode quick switch
Use siteConfig('<KEY>', <default>, CONFIG) consistently.
Recommended key groups:
THEME_MENU_*THEME_HERO_*THEME_POST_LIST_*THEME_WIDGET_*THEME_ARTICLE_*
Do not scatter constants in component bodies.
- Build minimum runnable skeleton (
LayoutBase,LayoutIndex,LayoutSlug, etc.). - Split large
index.jsinto focused components. - Port original style details (cards, banner, metadata density, transitions).
- Integrate NotionNext feature modules and config switches.
- Add docs for all theme config keys and default values.
- Run lint and verify:
- Home/list/search/archive/category/tag/article/404
- Light/dark mode
- Menu behaviors (
customNav,CUSTOM_MENU) - Notice, ads, plugin slot, contact card
For themes/fuwari, these specifics are already applied:
- Upstream style reference source: saicaca/fuwari
- Notion cover hero support
- Data-driven menu with
customNav/customMenucompatibility - Independent TOC, sidebar widgets, and right-float actions
- Flip contact card support via global
FlipCard
- Hardcoded menu paths without
customMenusupport. - Reusing another theme's UI components directly.
- Local-only dark mode toggle that ignores global context.
- Missing
post?.tocandnotice?.blockMapguards. - Forgetting to expose new behaviors in theme config.
- Layout orientation: desktop default should be left functional sidebar + right content feed.
- Hero full width: avoid
calc(50% - 50vw)scrollbar offset drift; use stable center transform strategy. - Post card variants:
- with cover: text left + cover right
- without cover: keep a right-side action rail to maintain visual rhythm
- Readmore affordance: right action rail and icon should keep consistent card height alignment.
- Profile card actions: include social icon row under avatar/bio if source theme has it.
- Theme color picker UX:
- trigger from top-right palette button
- use floating panel, not sidebar block
- real-time preview + persisted local setting
- expose copied hue/hex for operators to write back into
config.js
- Theme docs placement:
- avoid putting markdown docs under
themes/<theme>/if build pipeline treats theme dirs as runtime modules - place theme docs under
docs/themes/instead
- avoid putting markdown docs under
- Route transition feel: add lightweight page/card transition to mimic source theme interaction rhythm.