@djangocfg/layouts

中文文档
2.1.653发布于 2026/11/12MITTypeScriptESM + CJS近 30 天下载 1.5万

Simple, straightforward layout components for Next.js - import and use with props

原始使用文档
文档目录15 节
  1. Quick start
  2. Layouts
  3. Staff-only route groups
  4. AuthLayout shells
  5. ProfileLayout
  6. Theme
  7. i18n
  8. Monitor & debug
  9. MonitorBoundary
  10. Analytics and auth funnels
  11. Snippets
  12. Concepts and decisions
  13. Stories and tests
  14. Package exports
  15. License

@djangocfg/layouts

@djangocfg/layouts

Layouts, app shell, and providers for Next.js App Router. Part of DjangoCFG.

pnpm add @djangocfg/layouts
/* Golden path — bundles Tailwind + tokens + base + utilities, layer-safe */
@import "@djangocfg/ui-core/styles/full";
@import "@djangocfg/layouts/styles";

Peers: @djangocfg/ui-core, React 19, Next.js 16+, Tailwind CSS 4.


Quick start

Two responsibilities, kept separate:

  1. Providers — mount BaseApp ONCE at the app root (theme, auth, i18n, SWR, monitor, toasts). It's framework-agnostic (works in Wails/Vite too).
  2. Per-section shell — each Next.js route-group layout.tsx imports the matching shell (PrivateLayout / PublicLayout) and passes its own config. No runtime layout-router, no enabledPath matching.
// app/[locale]/layout.tsx — providers, once
import { BaseApp } from '@djangocfg/layouts';
<BaseApp project="my-app" theme={{ defaultTheme: 'system' }}
         auth={{ apiUrl: '…', routes: { auth: '/auth' } }}
         i18n={{ locale, locales, onLocaleChange: changeLocale, routing }}>
  {children}
</BaseApp>

// app/[locale]/(pages)/private/layout.tsx — the private shell
import { PrivateLayout } from '@djangocfg/layouts';
<PrivateLayout sidebar={sidebar} header={header}>{children}</PrivateLayout>

See the BaseApp README for the full provider surface and the Next.js vs Wails wiring, and the demo app (apps/demo/app/_layouts) for a complete reference.

Pass i18n when using next-intl or any locale-prefixed routing, so the link bridge and locale switcher resolve correctly.


Layouts

ComponentUseDocs
PublicLayoutMarketing / docs. Slots for navbar (Floating/Flush/Minimal) + footer + locale + auth controls.README
PrivateLayoutAuthenticated app shell — sidebar (collapsible icon rail, accordion groups, rail/featured/CTA slots) + popover account footer.README
AuthLayoutSign-in / sign-up flows. Shell-based: centered (default) or split (two-column desktop).README

Admin is not a separate layout — use PrivateLayout with an admin sidebar config in your app/.../admin/layout.tsx.

Staff-only route groups

PrivateLayout's guard checks the session. For a surface that also requires staff, add requireStaff (resolved from useAuth().isAdminUser, the is_staff || is_superuser fold):

<PrivateLayout sidebar={sidebar} header={header} requireStaff>{children}</PrivateLayout>

A signed-in non-staff user gets ForbiddenState instead of the shell — not a redirect to the auth form: they are already signed in, so signing in again cannot grant the privilege, and since the guard saves the current URL first, a redirect would loop back here. Pass forbiddenFallback to supply your own screen. Details: PrivateLayout README.

AuthLayout shells

Two visual variants, switchable via the variant prop:

  • centered — Apple HIG-style: frameless, centered form, animated glow background.
  • split — Two-column card on desktop (form left, customizable sidebar right); single-column on mobile. Background image/gradient with overlay + blur via the background prop.
// Split variant with background image and testimonial sidebar
<AuthLayout
  variant="split"
  background={{ imageUrl: '/bg.jpg', overlay: 'hsl(var(--background) / 0.6)', blur: '8px' }}
  sidebar={<Testimonial />}
>
  {/* optional custom header, shown only on identifier step */}
</AuthLayout>

Architecture: AuthShell orchestrator dispatches to CenteredShell or SplitShell. Add new variants by extending AuthShellVariant and creating a new shell component.

ProfileLayout

<ProfileLayout enable2FA enableDeleteAccount tabs={tabs} slots={slots} />
PropRole
enable2FAShow Security tab with 2FA management.
enableDeleteAccountShow Delete account in ⋯ menu.
tabsExtra ProfileTab[] appended after built-ins.
slots.headerBadge / headerMenuItems / headerAfter / footerSlot content around the avatar row, menu, and tab body.

Theme

Themes are selected by the host application's CSS import. BaseApp owns only the light/dark class and does not inject token styles at runtime:

@import "@djangocfg/ui-core/styles/full";
@import "@djangocfg/ui-core/styles/presets/macos";

The package exports ThemeStylePresetId and THEME_STYLE_PRESET_ORDER for metadata and selectors. Preset tokens live exclusively in the static CSS files shipped by @djangocfg/ui-core.


i18n

import { useLocaleSwitcher } from '@djangocfg/nextjs/i18n/client';
import { routing } from '@djangocfg/nextjs/i18n/routing';

const { locale, locales, changeLocale } = useLocaleSwitcher();
<BaseApp i18n={{ locale, locales, onLocaleChange: changeLocale, routing }}>...</BaseApp>

When routing is set, BaseApp mounts a locale-aware <Link> adapter so every layout-rendered link keeps the active locale prefix. Drop it for default-locale-only apps.


Monitor & debug

baseApp.project enables window.monitor. Debug panel: Cmd+D or ?debug=1.

MonitorBoundary

Error boundary that automatically reports caught errors to @djangocfg/devtools. Use at page/layout level so unexpected render errors land in your backend dashboard.

import { MonitorBoundary } from '@djangocfg/layouts';

export default function Layout({ children }) {
  return (
    <MonitorBoundary variant="fullscreen" name="root-layout">
      {children}
    </MonitorBoundary>
  );
}

// Per-section, non-fatal:
<MonitorBoundary variant="card" name="dashboard-stats" resetKeys={[pathname]}>
  <StatsPanel />
</MonitorBoundary>

// Opt out of reporting (e.g. third-party iframe noise):
<MonitorBoundary reportToMonitor={false} variant="silent">
  <EmbeddedWidget />
</MonitorBoundary>

Wraps Boundary from @djangocfg/ui-core — same variant/fallback/resetKeys API, plus auto FrontendMonitor.capture(...).

One top-level boundary. BaseApp already mounts the app-wide crash boundary (UiProviders' built-in one, fed an i18n fallback) — don't wrap a second one around the whole app. Use MonitorBoundary for per-section isolation (so one panel's crash doesn't take the page), not as a duplicate root boundary. All boundaries share the single ui-core Boundary catch.

For local UI widgets that should not report to backend, use Boundary from @djangocfg/ui-core directly.

Analytics and auth funnels

BaseApp mounts the first-party AnalyticsProvider once and bridges events from @djangocfg/api/auth. AuthLayout adds a small layouts.auth.step_viewed breadcrumb at each visible step; the server-confirmed auth_login_success event remains the conversion source of truth.

For a custom product goal, use useAnalytics().event(name, props) from @djangocfg/analytics. See that package's README for the typed event catalog, browser facade, and extension pattern. Do not create a second route listener or send analytics directly from a layout.


Snippets

Small surfaces a host mounts once, exported from @djangocfg/layouts and @djangocfg/layouts/snippets:

ExportWhat
AuthDialog, useAuthDialogThe global sign-in dialog. BaseApp mounts it with auth enabled; anything can open it, including a widget that only has dialogStore.
TwoFactorSetupEnrol flow for a settings page: QR, confirmation code, backup codes.
TwoFactorChallengeDialogThe code prompt that opens over the page when a sign-in step needs 2FA. AuthLayout mounts it.
AnalyticsRe-exported from @djangocfg/analytics for older imports; new code imports that package (see Analytics above).
BreadcrumbsBreadcrumbs from items, or from the current path when none are given.

Concepts and decisions

How the layouts fit together (scroll model, safe-area tokens, PWA/mobile behaviour, decision log): @docs/.

Stories and tests

@djangocfg/layouts/testing is for Storybook and tests only: MockAuthProvider and buildMockUser give useAuth() a fixed session, MockAuthFormProvider and the step components mount a sign-in step without the full AuthLayout. Do not import it from production code.


Package exports

PathContents
@djangocfg/layoutsBarrel.
@djangocfg/layouts/layoutsLayout components.
@djangocfg/layouts/snippetsAuthDialog, the 2FA surfaces, Breadcrumbs, Devtools, the analytics re-export.
@djangocfg/layouts/componentsMisc + ErrorLayout, RedirectPage.
@djangocfg/layouts/utilsPath matching and sidebar-navigation helpers, logger.
@djangocfg/layouts/pagesPage templates (legal).
@djangocfg/layouts/configuratorJSON Schemas for <JsonSchemaForm>-driven configurator UIs. Pair with @djangocfg/widget-forms.
@djangocfg/layouts/configurator/privateThe PrivateLayout configurator schema on its own.
@djangocfg/layouts/testingStorybook and test helpers; not for production code.
@djangocfg/layouts/stylesBase CSS.
@djangocfg/layouts/styles/dashboardDashboard shell CSS.

Extensions: @djangocfg/ext-newsletter, ext-knowbase, ext-leads, ext-payments, ext-support, …

License

MIT — DjangoCFG

版本与发布记录

@djangocfg/layouts 共发布 671 个版本,首次发布于 2025/10/13;过去 12 个月发布了 629 个版本。

版本发布日期距今
2.1.653latest2026/11/12今天
2.1.6522026/11/11今天
2.1.6512026/11/111 天前
2.1.6502026/11/111 天前
2.1.6482026/11/111 天前
2.1.6472026/11/111 天前

关于 @djangocfg/layouts 的常见问题

@djangocfg/layouts 是什么?

Simple, straightforward layout components for Next.js - import and use with props

如何安装 @djangocfg/layouts?

在项目目录运行 npm install @djangocfg/layouts,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:swr(^2.3.7)、zod(^4.3.6)、next(^16.4.5)、react(^19.0.0)、moment(^2.30.1)、sonner(^2.0.7)、consola(^3.4.2)、p-retry(^7.0.0)、zustand(^5.0.0)、next-intl(^4.9.1)、react-dom(^19.0.0)、tailwindcss(^4.1.18)、lucide-react(^1.68.0)、@djangocfg/api(^2.1.653)、@djangocfg/i18n(^2.1.653)、react-hook-form(^7.69.0)、@djangocfg/ui-core(^2.1.653)、@hookform/resolvers(^5.2.2 || ^7.0.2)、tailwindcss-animate(^1.0.7)、@djangocfg/analytics(^2.1.653)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@djangocfg/layouts 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@djangocfg/layouts 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@djangocfg/layouts 可以商用吗?

@djangocfg/layouts 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@djangocfg/layouts 的下载量有多少?

根据 npm 官方下载统计,@djangocfg/layouts 在 2026/10/13 – 2026/11/11 这 30 天内被下载 15,306 次,日均约 510 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@djangocfg/layouts 还在维护吗?

最新版本 2.1.653 发布于 2026/11/12(今天);至今共发布 671 个版本,其中过去 12 个月发布了 629 个;首次发布于 2025/10/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。