@djangocfg/layouts
Simple, straightforward layout components for Next.js - import and use with props.
Part of DjangoCFG β modern Django framework for production-ready SaaS applications.
Install
pnpm add @djangocfg/layouts
Core Components
BaseApp
Core providers wrapper - use when you need providers without layout routing:
import { BaseApp } from '@djangocfg/layouts';
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<BaseApp theme={{ defaultTheme: 'dark' }}>
{children}
</BaseApp>
</body>
</html>
);
}
Included providers:
- ThemeProvider (light/dark/system)
- TooltipProvider
- SWRConfig
- AuthProvider (from
@djangocfg/api)
- ErrorTrackingProvider
- Toaster + PageProgress
Note: Auth functionality is provided by @djangocfg/api package. See @djangocfg/api documentation for auth usage.
AppLayout
Smart layout router built on BaseApp - automatically selects layout based on route:
import { AppLayout } from '@djangocfg/layouts';
import { PublicLayout } from './_layouts/PublicLayout';
import { PrivateLayout } from './_layouts/PrivateLayout';
export default function RootLayout({ children }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<AppLayout
publicLayout={{
component: PublicLayout,
enabledPath: ['/', '/legal', '/contact']
}}
privateLayout={{
component: PrivateLayout,
enabledPath: ['/dashboard', '/profile']
}}
theme={{ defaultTheme: 'system' }}
>
{children}
</AppLayout>
</body>
</html>
);
}
Layout priority: Admin β Private β Public β Fallback
Layouts
Simple, props-based layout components. No complex configs needed!
Available Layouts
import { PublicLayout, PrivateLayout, AuthLayout } from '@djangocfg/layouts';
<PublicLayout
logo="/logo.svg"
siteName="My App"
navigation={navItems}
>
{children}
</PublicLayout>
<PrivateLayout
sidebar={{ items: menuItems }}
header={{ title: 'Dashboard' }}
>
{children}
</PrivateLayout>
<AuthLayout
logo="/logo.svg"
title="Sign In"
subtitle="Welcome back"
>
<LoginForm />
</AuthLayout>
BaseApp | Core providers wrapper (Theme, Auth, SWR, ErrorTracking, Toaster) |
AppLayout | Smart layout router with route-based layout switching |
PublicLayout | Public pages (home, docs, contact, legal) |
PrivateLayout | Authenticated user pages (dashboard, profile) |
AuthLayout | Authentication pages (login, signup, password reset) |
AdminLayout | Admin panel layout |
ProfileLayout | User profile pages |
Extension Layouts: Additional layouts like SupportLayout and PaymentsLayout are available in extension packages:
@djangocfg/ext-support - Support ticket layouts
@djangocfg/ext-payments - Payment flow layouts
Analytics
Google Analytics integration via react-ga4. Auto-tracks pageviews and user sessions.
Setup
Add tracking ID to your config:
export const appLayoutConfig: AppLayoutConfig = {
analytics: {
googleTrackingId: 'G-XXXXXXXXXX',
},
};
Analytics is automatically initialized by AppLayout. Works only in production (NODE_ENV === 'production').
Usage
import { useAnalytics, Analytics, AnalyticsEvent, AnalyticsCategory } from '@djangocfg/layouts';
const { event, isEnabled } = useAnalytics();
event(AnalyticsEvent.THEME_CHANGE, {
category: AnalyticsCategory.ENGAGEMENT,
label: 'dark',
});
Analytics.event('button_click', { category: 'engagement', label: 'signup' });
Analytics.setUser('user-123');
Predefined Events
| Auth | AUTH_LOGIN_SUCCESS, AUTH_LOGOUT, AUTH_SESSION_EXPIRED, AUTH_TOKEN_REFRESH |
| OAuth | AUTH_OAUTH_START, AUTH_OAUTH_SUCCESS, AUTH_OAUTH_FAIL |
| Error | ERROR_BOUNDARY, ERROR_API, ERROR_VALIDATION, ERROR_NETWORK |
| Navigation | NAV_ADMIN_ENTER, NAV_DASHBOARD_ENTER, NAV_PAGE_VIEW |
| Engagement | THEME_CHANGE, SIDEBAR_TOGGLE, MOBILE_MENU_OPEN |
Auto-tracking
Built-in tracking for:
- Page views - on every route change
- User ID - automatically set when user is authenticated
- Auth events - login, logout, session expiry (from
@djangocfg/api)
- OAuth events - GitHub OAuth start, success, failure
- Errors - React ErrorBoundary errors
Snippets
Reusable UI components ready to use.
import {
Breadcrumbs,
AuthDialog,
} from '@djangocfg/layouts/snippets';
Breadcrumbs | Navigation breadcrumbs with automatic path generation |
AuthDialog | Auth modal (login/register) with event-based triggers |
AnalyticsProvider | Analytics wrapper component |
Extension Snippets: Additional components are available in extension packages:
@djangocfg/ext-leads - ContactForm, ContactPage, ContactInfo
@djangocfg/ext-knowbase - KnowledgeChat, ChatWidget, ChatUIProvider
@djangocfg/ext-newsletter - Hero (with newsletter subscription)
Breadcrumbs
import Breadcrumbs from '@djangocfg/layouts/snippets';
<Breadcrumbs />
<Breadcrumbs
items={[
{ path: '/', label: 'Home', isActive: false },
{ path: '/products', label: 'Products', isActive: true },
]}
/>
AuthDialog
import { AuthDialog, openAuthDialog } from '@djangocfg/layouts/snippets';
<AuthDialog authPath="/auth" />
openAuthDialog({ message: 'Sign in to continue' });
Components
Utility components organized by category.
Core Components
import {
JsonLd,
LucideIcon,
PageProgress,
Suspense
} from '@djangocfg/layouts/components/core';
JsonLd | JSON-LD structured data component |
LucideIcon | Lucide icon wrapper component |
PageProgress | Page loading progress indicator |
Suspense | Suspense wrapper component |
Error Components
import {
ErrorBoundary,
ErrorLayout,
getErrorContent,
ERROR_CODES
} from '@djangocfg/layouts/components/errors';
ErrorBoundary | React error boundary component |
ErrorLayout | Reusable error page layout (404, 500, etc.) |
getErrorContent | Get error content by status code |
ERROR_CODES | Common HTTP error code constants |
ErrorLayout Usage:
import { ErrorLayout } from '@djangocfg/layouts/components/errors';
export default function NotFound() {
return <ErrorLayout code={404} supportEmail="support@example.com" />;
}
'use client';
import { ErrorLayout } from '@djangocfg/layouts/components/errors';
export default function Error({ error, reset }) {
return <ErrorLayout code={500} supportEmail="support@example.com" />;
}
Redirect Component
import { RedirectPage } from '@djangocfg/layouts/components/RedirectPage';
export default function Page() {
return (
<RedirectPage
authenticatedPath="/dashboard"
unauthenticatedPath="/auth"
loadingText="Loading..."
/>
);
}
Error Tracking
import {
ErrorTrackingProvider,
useErrors,
ErrorButtons,
ErrorToast
} from '@djangocfg/layouts/components/errors/ErrorsTracker';
<ErrorTrackingProvider>
<YourApp />
</ErrorTrackingProvider>
const { addError, clearErrors, errors } = useErrors();
Update Notifier
import { UpdateNotifier } from '@djangocfg/layouts/components/UpdateNotifier';
<UpdateNotifier />
Pages
Ready-to-use page components.
Legal Pages
Pre-built legal page components with default configurations.
import {
PrivacyPage,
TermsPage,
CookiesPage,
SecurityPage
} from '@djangocfg/layouts/pages/legal';
export default PrivacyPage;
import { PrivacyPage, privacyConfig } from '@djangocfg/layouts/pages/legal';
export default function CustomPrivacy() {
return <PrivacyPage config={{
...privacyConfig,
lastUpdated: '2024-01-01',
}} />;
}
PrivacyPage | Privacy policy page |
TermsPage | Terms of service page |
CookiesPage | Cookie policy page |
SecurityPage | Security policy page |
Utils
Utility functions and helpers.
import {
generateOgImageUrl,
getAbsoluteOgImageUrl,
createOgImageUrlBuilder
} from '@djangocfg/layouts/utils/og-image';
const ogUrl = generateOgImageUrl('/api/og', {
title: 'My Page',
description: 'Page description',
siteName: 'My Site',
});
generateOgImageUrl | Generate OG image URL with base64 encoding |
getAbsoluteOgImageUrl | Get absolute OG image URL |
createOgImageUrlBuilder | Create OG image URL builder with defaults |
Exports
@djangocfg/layouts | Main exports (all modules) |
@djangocfg/layouts/layouts | Layout components |
@djangocfg/layouts/snippets | Reusable components + Analytics |
@djangocfg/layouts/components | All utility components |
@djangocfg/layouts/pages | Page components (legal pages) |
@djangocfg/layouts/pages/legal | Legal page components |
@djangocfg/layouts/utils | Utilities (og-image, logger) |
@djangocfg/layouts/styles | CSS |
@djangocfg/layouts/styles/dashboard | Dashboard-specific CSS |
Auth Exports: For authentication, use @djangocfg/api/auth - See @djangocfg/api documentation
Extension Packages
Additional functionality is available in extension packages:
| Newsletter | @djangocfg/ext-newsletter | Newsletter subscription and campaigns |
| Knowledge Base | @djangocfg/ext-knowbase | Documentation, chat, RAG-powered AI |
| Leads | @djangocfg/ext-leads | Lead capture and contact forms |
| Payments | @djangocfg/ext-payments | Payment processing and subscriptions |
| Support | @djangocfg/ext-support | Support tickets and helpdesk |
Each extension has its own layouts, contexts, and components. See individual extension documentation for details.
Requirements
- Next.js >= 15
- React >= 19
- Tailwind CSS >= 4
- react-ga4 (bundled)
- @djangocfg/ui-nextjs (peer dependency)
- @djangocfg/api (peer dependency)
Philosophy
This package follows a simple, props-based approach:
- β
No complex configs - just pass props
- β
Type-safe - full TypeScript support
- β
Flexible - compose layouts as needed
- β
Production-ready - built for real apps
- β
Modular - core layouts in one package, extensions separate
Examples
Complete App Setup
import { AppLayout } from '@djangocfg/layouts';
import { appLayoutConfig } from './_config/appLayoutConfig';
export default function RootLayout({ children }) {
return (
<AppLayout config={appLayoutConfig}>
{children}
</AppLayout>
);
}
Public Page
import { PublicLayout } from '@djangocfg/layouts';
export default function HomePage() {
return (
<PublicLayout
logo="/logo.svg"
siteName="My App"
navigation={[
{ label: 'Home', href: '/' },
{ label: 'Docs', href: '/docs' },
{ label: 'Contact', href: '/contact' }
]}
>
<h1>Welcome</h1>
</PublicLayout>
);
}
Private Dashboard
import { PrivateLayout } from '@djangocfg/layouts';
export default function DashboardPage() {
return (
<PrivateLayout
sidebar={{
items: [
{ label: 'Dashboard', href: '/dashboard', icon: 'LayoutDashboard' },
{ label: 'Settings', href: '/settings', icon: 'Settings' }
]
}}
header={{
title: 'Dashboard',
userMenu: { name: 'John Doe', email: 'john@example.com' }
}}
>
<h1>Dashboard</h1>
</PrivateLayout>
);
}
Auth Page
import { AuthLayout } from '@djangocfg/layouts';
import { LoginForm } from './_components/LoginForm';
export default function LoginPage() {
return (
<AuthLayout
logo="/logo.svg"
siteName="My App"
title="Sign In"
subtitle="Welcome back! Please sign in to continue."
>
<LoginForm />
</AuthLayout>
);
}
License
MIT
Links