Socket
Book a DemoInstallSign in
Socket

@djangocfg/layouts

Package Overview
Dependencies
Maintainers
1
Versions
167
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@djangocfg/layouts

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

latest
Source
npmnpm
Version
2.1.65
Version published
Weekly downloads
3K
28.52%
Maintainers
1
Weekly downloads
 
Created
Source

@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';

// app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <BaseApp
          theme={{ defaultTheme: 'dark' }}
          analytics={{ googleTrackingId: 'G-XXXXXXXXXX' }}
          centrifugo={{ enabled: true, url: process.env.NEXT_PUBLIC_CENTRIFUGO_URL }}
          pwaInstall={{ enabled: true, showInstallHint: true }}
          pushNotifications={{
            enabled: true,
            vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_KEY || ''
          }}
          mcpChat={{ enabled: true, autoDetectEnvironment: true }}
        >
          {children}
        </BaseApp>
      </body>
    </html>
  );
}

Included providers:

  • ThemeProvider - Light/dark/system theme management
  • TooltipProvider - Tooltip positioning context
  • SWRConfig - Data fetching configuration
  • AuthProvider - Authentication context (from @djangocfg/api)
  • AnalyticsProvider - Google Analytics (optional)
  • CentrifugoProvider - WebSocket real-time (optional)
  • PwaProvider - PWA installation (optional)
  • DjangoPushProvider - Django web push integration with history (optional)
  • ErrorTrackingProvider - Error handling and tracking
  • ErrorBoundary - React error boundary
  • MCP Chat Widget - AI chat assistant (optional)

Global components:

  • PageProgress - NProgress bar for route changes
  • Toaster - Toast notifications container
  • A2HSHint - PWA install hint (if enabled)
  • PushPrompt - Push notification prompt (if enabled)

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';
import { AdminLayout } from './_layouts/AdminLayout';

// app/layout.tsx
export default function RootLayout({ children }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <AppLayout
          // Provider configs (passed to BaseApp)
          theme={{ defaultTheme: 'system' }}
          analytics={{ googleTrackingId: 'G-XXXXXXXXXX' }}
          pwaInstall={{ enabled: true }}
          pushNotifications={{
            enabled: true,
            vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_KEY || ''
          }}

          // Layout components
          publicLayout={{
            component: PublicLayout,
            enabledPath: ['/', '/legal', '/contact']
          }}
          privateLayout={{
            component: PrivateLayout,
            enabledPath: ['/dashboard', '/profile']
          }}
          adminLayout={{
            component: AdminLayout,
            enabledPath: '/admin'
          }}

          // Skip layout for fullscreen pages (providers still applied)
          noLayoutPaths={['/private/terminal', '/embed']}
        >
          {children}
        </AppLayout>
      </body>
    </html>
  );
}

Layout priority: Admin → Private → Public → Fallback

noLayoutPaths: Paths that render without any layout wrapper. Useful for fullscreen pages (terminal, embed, print). Providers (auth, theme, centrifugo) are still applied.

Layouts

Simple, props-based layout components. No complex configs needed!

Available Layouts

import { PublicLayout, PrivateLayout, AuthLayout } from '@djangocfg/layouts';

// Public page
<PublicLayout
  logo="/logo.svg"
  siteName="My App"
  navigation={navItems}
>
  {children}
</PublicLayout>

// Private page
<PrivateLayout
  sidebar={{ items: menuItems }}
  header={{ title: 'Dashboard' }}
>
  {children}
</PrivateLayout>

// Auth page
<AuthLayout
  logo="/logo.svg"
  title="Sign In"
  subtitle="Welcome back"
>
  <LoginForm />
</AuthLayout>
LayoutDescription
BaseAppCore providers wrapper (Theme, Auth, SWR, ErrorTracking, Toaster)
AppLayoutSmart layout router with route-based layout switching
PublicLayoutPublic pages (home, docs, contact, legal)
PrivateLayoutAuthenticated user pages (dashboard, profile)
AuthLayoutAuthentication pages (login, signup, password reset)
AdminLayoutAdmin panel layout
ProfileLayoutUser 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:

// appLayoutConfig.ts
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';

// In React components - auto-tracks pageviews
const { event, isEnabled } = useAnalytics();

event(AnalyticsEvent.THEME_CHANGE, {
  category: AnalyticsCategory.ENGAGEMENT,
  label: 'dark',
});

// Outside React (utilities, handlers)
Analytics.event('button_click', { category: 'engagement', label: 'signup' });
Analytics.setUser('user-123');

Predefined Events

CategoryEvents
AuthAUTH_LOGIN_SUCCESS, AUTH_LOGOUT, AUTH_SESSION_EXPIRED, AUTH_TOKEN_REFRESH
OAuthAUTH_OAUTH_START, AUTH_OAUTH_SUCCESS, AUTH_OAUTH_FAIL
ErrorERROR_BOUNDARY, ERROR_API, ERROR_VALIDATION, ERROR_NETWORK
NavigationNAV_ADMIN_ENTER, NAV_DASHBOARD_ENTER, NAV_PAGE_VIEW
EngagementTHEME_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

PWA & Push Notifications

Progressive Web App features and Web Push notifications support.

PWA Installation

Enable PWA installation prompts with pwaInstall config:

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

<BaseApp
  pwaInstall={{
    enabled: true,
    showInstallHint: true,      // Show A2HS hint
    resetAfterDays: 3,           // Re-show after dismissal
    delayMs: 1000,               // Delay before showing
    logo: '/logo192.png',        // PWA logo
    resumeLastPage: true,        // Resume last page on PWA launch
  }}
>
  {children}
</BaseApp>

Features:

  • A2HSHint - Platform-specific install hints (iOS Safari/Chrome/Firefox, Android Chrome, Desktop)
  • Page Resume - Automatically navigate to last viewed page when PWA is launched
  • Auto-detection - Detects if running as PWA
  • Dismissal tracking - Respects user dismissal with localStorage
  • Custom timing - Configurable delay and reset periods

Page Resume: When resumeLastPage: true, the app saves the current pathname on every navigation and restores it when the PWA is launched. Pages like /auth, /login, /error are automatically excluded. Data expires after 24 hours.

Push Notifications

Enable Web Push notifications with pushNotifications config:

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

<BaseApp
  pushNotifications={{
    enabled: true,
    vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_KEY || '',
    subscribeEndpoint: '/api/push/subscribe',  // Backend subscription endpoint
    requirePWA: true,                          // Only show if installed as PWA
    autoSubscribe: false,                      // Auto-subscribe on install
    delayMs: 5000,                             // Delay before showing prompt
    resetAfterDays: 7,                         // Re-show after dismissal
  }}
>
  {children}
</BaseApp>

Features:

  • PushPrompt - Permission request prompt
  • VAPID authentication - Secure push with VAPID keys
  • Subscription management - Auto-subscribe and unsubscribe
  • PWA integration - Can require PWA installation first
  • Custom timing - Configurable delay and reset

Usage

import { usePwa, useDjangoPushContext } from '@djangocfg/layouts/snippets';

// PWA status
const { isPWA, isInstallable } = usePwa();

// Push notifications (Django integration)
const {
  isSupported,
  isSubscribed,
  permission,
  pushes,
  subscribe,
  unsubscribe,
  sendPush,
  clearPushes,
  removePush,
} = useDjangoPushContext();

// Subscribe to push
await subscribe();

// Send test notification (via Django API)
await sendPush({
  title: 'Hello!',
  body: 'Test notification',
  icon: '/icon.png',
});

// Manage push history
clearPushes(); // Clear all
removePush(pushId); // Remove specific push

VAPID Keys Generation

Generate VAPID keys for push notifications:

# Using web-push CLI
npx web-push generate-vapid-keys

# Or use openssl
openssl ecparam -name prime256v1 -genkey -noout -out vapid_private.pem
openssl ec -in vapid_private.pem -pubout -out vapid_public.pem

Add keys to .env.local:

NEXT_PUBLIC_VAPID_PUBLIC_KEY=your_public_key_here
VAPID_PRIVATE_KEY=your_private_key_here

Snippets

Reusable UI components and hooks ready to use.

import {
  Breadcrumbs,
  AuthDialog,
  usePwa,
  useDjangoPushContext,
} from '@djangocfg/layouts/snippets';
SnippetDescription
BreadcrumbsNavigation breadcrumbs with automatic path generation
AuthDialogAuth modal (login/register) with event-based triggers
AnalyticsProviderAnalytics wrapper component
usePwaPWA status hook (isPWA, isInstallable, etc.)
usePWAPageResumeResume last page on PWA launch
useDjangoPushContextDjango push notifications hook (subscribe, send, history)
usePushGeneric push hook (for non-Django apps)
A2HSHintAdd to Home Screen hint component
PWAPageResumeManagerComponent for PWA page resume (use via BaseApp config)
PushPromptPush notification permission prompt

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';

// Auto-generate from current path
<Breadcrumbs />

// Or provide custom items
<Breadcrumbs
  items={[
    { path: '/', label: 'Home', isActive: false },
    { path: '/products', label: 'Products', isActive: true },
  ]}
/>

AuthDialog

import { AuthDialog, openAuthDialog } from '@djangocfg/layouts/snippets';

// Add to layout
<AuthDialog authPath="/auth" />

// Trigger from anywhere
openAuthDialog({ message: 'Sign in to continue' });

Components

Utility components organized by category.

Core Components

import {
  JsonLd,
  LucideIcon,
  PageProgress,
  Suspense
} from '@djangocfg/layouts/components/core';
ComponentDescription
JsonLdJSON-LD structured data component
LucideIconLucide icon wrapper component
PageProgressPage loading progress indicator
SuspenseSuspense wrapper component

Error Components

import {
  ErrorBoundary,
  ErrorLayout,
  getErrorContent,
  ERROR_CODES
} from '@djangocfg/layouts/components/errors';
ComponentDescription
ErrorBoundaryReact error boundary component
ErrorLayoutReusable error page layout (404, 500, etc.)
getErrorContentGet error content by status code
ERROR_CODESCommon HTTP error code constants

ErrorLayout Usage:

// app/not-found.tsx
import { ErrorLayout } from '@djangocfg/layouts/components/errors';

export default function NotFound() {
  return <ErrorLayout code={404} supportEmail="support@example.com" />;
}

// app/error.tsx
'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';

// app/page.tsx
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>

// In components
const { addError, clearErrors, errors } = useErrors();

Update Notifier

import { UpdateNotifier } from '@djangocfg/layouts/components/UpdateNotifier';

<UpdateNotifier />

Pages

Ready-to-use page components.

Pre-built legal page components with default configurations.

import {
  PrivacyPage,
  TermsPage,
  CookiesPage,
  SecurityPage
} from '@djangocfg/layouts/pages/legal';

// app/legal/privacy/page.tsx
export default PrivacyPage;

// Or customize
import { PrivacyPage, privacyConfig } from '@djangocfg/layouts/pages/legal';

export default function CustomPrivacy() {
  return <PrivacyPage config={{
    ...privacyConfig,
    lastUpdated: '2024-01-01',
  }} />;
}
PageDescription
PrivacyPagePrivacy policy page
TermsPageTerms of service page
CookiesPageCookie policy page
SecurityPageSecurity policy page

Utils

Utility functions and helpers.

import {
  generateOgImageUrl,
  getAbsoluteOgImageUrl,
  createOgImageUrlBuilder
} from '@djangocfg/layouts/utils/og-image';

// Generate OG image URL
const ogUrl = generateOgImageUrl('/api/og', {
  title: 'My Page',
  description: 'Page description',
  siteName: 'My Site',
});
UtilityDescription
generateOgImageUrlGenerate OG image URL with base64 encoding
getAbsoluteOgImageUrlGet absolute OG image URL
createOgImageUrlBuilderCreate OG image URL builder with defaults

Exports

PathContent
@djangocfg/layoutsMain exports (all modules)
@djangocfg/layouts/layoutsLayout components
@djangocfg/layouts/snippetsReusable components + Analytics
@djangocfg/layouts/componentsAll utility components
@djangocfg/layouts/pagesPage components (legal pages)
@djangocfg/layouts/pages/legalLegal page components
@djangocfg/layouts/utilsUtilities (og-image, logger)
@djangocfg/layouts/stylesCSS
@djangocfg/layouts/styles/dashboardDashboard-specific CSS

Auth Exports: For authentication, use @djangocfg/api/auth - See @djangocfg/api documentation

Extension Packages

Additional functionality is available in extension packages:

ExtensionPackageDescription
Newsletter@djangocfg/ext-newsletterNewsletter subscription and campaigns
Knowledge Base@djangocfg/ext-knowbaseDocumentation, chat, RAG-powered AI
Leads@djangocfg/ext-leadsLead capture and contact forms
Payments@djangocfg/ext-paymentsPayment processing and subscriptions
Support@djangocfg/ext-supportSupport 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

// app/layout.tsx
import { AppLayout } from '@djangocfg/layouts';
import { appLayoutConfig } from './_config/appLayoutConfig';

export default function RootLayout({ children }) {
  return (
    <AppLayout config={appLayoutConfig}>
      {children}
    </AppLayout>
  );
}

Public Page

// app/page.tsx
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

// app/dashboard/page.tsx
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 (OTP + 2FA Authentication)

// app/auth/page.tsx
'use client';

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

export default function AuthPage() {
  return (
    <AuthLayout
      sourceUrl="https://example.com"
      supportUrl="/support"
      termsUrl="/terms"
      privacyUrl="/privacy"
      enablePhoneAuth={false}
      enableGithubAuth={true}
      logoUrl="/logo.svg"
      redirectUrl="/dashboard"
      onOTPSuccess={() => {
        console.log('Authentication successful');
      }}
      onOAuthSuccess={(user, isNewUser, provider) => {
        console.log('OAuth success:', { user, isNewUser, provider });
      }}
    >
      <div className="text-center mb-6">
        <h2 className="text-2xl font-bold">Welcome to My App</h2>
        <p className="text-muted-foreground mt-2">
          Sign in with your email or phone
        </p>
      </div>
    </AuthLayout>
  );
}

Authentication Flow:

  • Identifier → Enter email/phone or click GitHub OAuth
  • OTP → Enter 6-digit verification code
  • 2FA → Enter TOTP code (if 2FA enabled for user)
  • Success → Show logo animation, then redirect

AuthLayout Props:

PropTypeDescription
sourceUrlstringApplication URL for OTP emails
redirectUrlstringURL to redirect after successful auth (default: /dashboard)
logoUrlstringLogo URL for success screen (SVG recommended)
enablePhoneAuthbooleanEnable phone number authentication
enableGithubAuthbooleanEnable GitHub OAuth
enable2FASetupbooleanEnable 2FA setup prompt after login (default: true). Set to false to skip 2FA setup prompt - users can then configure 2FA from ProfileLayout instead.
termsUrlstringTerms of service URL (shows checkbox if provided)
privacyUrlstringPrivacy policy URL
supportUrlstringSupport page URL
onOTPSuccess() => voidCallback after successful authentication
onOAuthSuccess(user, isNewUser, provider) => voidCallback after successful OAuth
onError(message: string) => voidError callback

Profile Page (with 2FA Management)

// app/profile/page.tsx
'use client';

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

export default function ProfilePage() {
  return (
    <ProfileLayout
      title="Profile Settings"
      description="Manage your account"
      enable2FA={true}  // Show 2FA management section
      showMemberSince={true}
      showLastLogin={true}
      onUnauthenticated={() => {
        // Redirect to login
      }}
    />
  );
}

ProfileLayout Props:

PropTypeDescription
titlestringPage title (default: "Profile Settings")
descriptionstringPage description
enable2FAbooleanShow 2FA management section (default: false). When enabled, users can enable/disable Two-Factor Authentication from their profile.
showMemberSincebooleanShow member since date (default: true)
showLastLoginbooleanShow last login date (default: true)
onUnauthenticated() => voidCallback when user is not authenticated

2FA Configuration Strategy:

  • Use enable2FASetup={false} in AuthLayout to skip post-login 2FA setup prompt
  • Use enable2FA={true} in ProfileLayout to allow users to manage 2FA from settings
  • This gives users control over when to enable 2FA instead of forcing it during login

License

MIT

Keywords

layouts

FAQs

Package last updated on 23 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts