npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@djangocfg/nextjs

v2.1.260

Published

Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config

Readme

@djangocfg/nextjs

@djangocfg/nextjs

Server-side Next.js utilities: OG images, sitemap, health checks, i18n, PWA, navigation, and config

npm version License: MIT

Part of DjangoCFG — a modern Django framework for building production-ready SaaS applications. All @djangocfg/* packages are designed to work together, providing type-safe configuration, real-time features, and beautiful admin interfaces out of the box.


Overview

@djangocfg/nextjs provides server-side utilities for Next.js applications built on top of Django-CFG.

Note: Client components (legal pages, error pages, redirect components) are in @djangocfg/layouts.

Features

  • OG Images — typed URL builder for Django's django_ogimage renderer (@djangocfg/nextjs/og-image)
  • i18n — full next-intl integration with routing, middleware, and components
  • PWA — zero-config service worker and manifest
  • Base Next.js Config — reusable createBaseNextConfig() factory for monorepos
  • Sitemap — dynamic XML sitemap with i18n hreflang support
  • Health Checks — production-ready health monitoring endpoints
  • Navigation — route definitions, menu generation, and active-state helpers
  • AI Documentation — search DjangoCFG docs via MCP server and CLI

Installation

npm install @djangocfg/nextjs
# or
pnpm add @djangocfg/nextjs
# or
yarn add @djangocfg/nextjs

Quick Start

AI Documentation Search

Search DjangoCFG documentation from the terminal:

# CLI (works anywhere via npx)
npx @djangocfg/nextjs ai-docs search "database configuration"
npx @djangocfg/nextjs ai-docs mcp

Or use the TypeScript API:

import { search, getDocs, getMcpConfig } from '@djangocfg/nextjs/ai';

// Search documentation
const results = await search('database configuration');
results.forEach(r => console.log(r.title, r.url));

// Get formatted docs
const docs = await getDocs('How to configure PostgreSQL?');

// Get MCP server config for AI assistants
const config = getMcpConfig();

MCP Server for AI Assistants

Add to your AI assistant configuration:

{
  "mcpServers": {
    "djangocfg-docs": {
      "url": "https://mcp.djangocfg.com/mcp"
    }
  }
}

Base Next.js Configuration

Create a reusable base configuration for all your Next.js projects:

// next.config.ts
import { createBaseNextConfig } from '@djangocfg/nextjs/config';
import bundleAnalyzer from '@next/bundle-analyzer';

const withBundleAnalyzer = bundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
});

export default withBundleAnalyzer(createBaseNextConfig({
  // Base path for static builds
  basePath: process.env.NEXT_PUBLIC_STATIC_BUILD === 'true' ? '/cfg/admin' : undefined,
  
  // Add custom transpile packages
  transpilePackages: ['my-custom-package'],
  
  // Custom webpack configuration (called after base webpack logic)
  webpack: (config, options) => {
    // Your custom webpack rules
    return config;
  },
}));

PWA (Progressive Web App)

Zero-config PWA - Works out of the box! Service worker and offline support included automatically.

1. Create manifest

// app/manifest.ts
import { createManifest, createScreenshots } from '@djangocfg/nextjs/config';
import { settings } from '@core/settings';

export default createManifest({
  name: settings.app.name,
  description: settings.app.description,
  themeColor: '#ffffff',
  backgroundColor: '#000000',
  icons: {
    logo192: settings.app.icons.logo192,
    logo384: settings.app.icons.logo384,
    logo512: settings.app.icons.logo512,
  },
  // Optional: Add screenshots for Richer PWA Install UI
  // IMPORTANT: Image dimensions must match sizes parameter!
  // screenshots: createScreenshots([
  //   '/screenshots/desktop-1920x1080.png',  // Wide: 1920x1080
  //   '/screenshots/mobile-390x844.png',     // Narrow: 390x844
  // ]),
});

2. Add manifest metadata

// app/layout.tsx
import { createManifestMetadata } from '@djangocfg/nextjs/config';

export const metadata = {
  ...createManifestMetadata({
    name: 'My App',
    themeColor: '#000000',
  }),
};

That's it! PWA is now enabled in production. Generated files:

  • /manifest.webmanifest - From app/manifest.ts
  • /sw.js - Service worker (auto-generated in production)
  • /workbox-*.js - Workbox runtime

Customization (optional):

// next.config.ts
export default createBaseNextConfig({
  pwa: {
    dest: 'public',
    disable: process.env.NODE_ENV === 'development', // Disable in dev
    fallbacks: {
      document: '/_offline', // Offline page
    },
    runtimeCaching: [
      // Custom caching rules
      ...defaultRuntimeCaching,
      createApiCacheRule('https://api.example.com'),
    ],
  },
});

See PWA.md for complete guide.

i18n (Internationalization)

Full next-intl integration for multilingual Next.js apps.

Important: Use subpath imports to avoid React Context issues in server components:

  • @djangocfg/nextjs/i18n - Types only
  • @djangocfg/nextjs/i18n/routing - routing, createRouting, generateLocaleParams
  • @djangocfg/nextjs/i18n/client - I18nProvider, hooks
  • @djangocfg/nextjs/i18n/components - LocaleSwitcher

1. Create middleware (proxy.ts)

// proxy.ts (or middleware.ts)
import createMiddleware from 'next-intl/middleware';
import { routing } from '@djangocfg/nextjs/i18n/routing';

export default createMiddleware(routing);

export const config = {
  matcher: ['/((?!api|_next|_vercel|.*\\..*).*)',],
};

2. Create i18n request config

// i18n/request.ts
import { getRequestConfig } from 'next-intl/server';
import { en, ru, ko } from '@djangocfg/i18n/locales';
import { mergeTranslations } from '@djangocfg/i18n/utils';

const locales = {
  en: mergeTranslations(en, { app: appEn }),
  ru: mergeTranslations(ru, { app: appRu }),
  ko: mergeTranslations(ko, { app: appKo }),
};

export default getRequestConfig(async ({ requestLocale }) => {
  let locale = await requestLocale;
  if (!locale || !(locale in locales)) locale = 'en';

  return {
    locale,
    messages: locales[locale],
    timeZone: 'UTC',
  };
});

3. Use in layout

// app/[locale]/layout.tsx
import { getMessages } from 'next-intl/server';
import { I18nProvider } from '@djangocfg/nextjs/i18n/client';
import { routing, generateLocaleParams } from '@djangocfg/nextjs/i18n/routing';

export function generateStaticParams() {
  return generateLocaleParams();
}

export default async function LocaleLayout({ children, params }) {
  const { locale } = await params;
  const messages = await getMessages();

  return (
    <I18nProvider locale={locale} messages={messages}>
      {children}
    </I18nProvider>
  );
}

4. Use translations in components

'use client';
import { useTranslations } from 'next-intl';

function MyComponent() {
  const t = useTranslations('app');
  return <h1>{t('title')}</h1>;
}

Locale Switcher

Smart wrapper around @djangocfg/layouts LocaleSwitcher with automatic next-intl hooks:

import { LocaleSwitcher } from '@djangocfg/nextjs/i18n/components';

// Basic usage (automatically gets locale from next-intl)
<LocaleSwitcher />

// With custom locales (override routing config)
<LocaleSwitcher locales={['en', 'ru']} />

// With custom labels and styling
<LocaleSwitcher
  labels={{ en: 'English', ru: 'Русский' }}
  variant="outline"
  size="sm"
/>

Note: This component wraps @djangocfg/layouts LocaleSwitcher with useLocaleSwitcher() hook. For a presentational version that accepts locale data via props, use LocaleSwitcher from @djangocfg/layouts directly.

Sitemap Generation

Generate dynamic XML sitemaps with i18n hreflang support:

// app/sitemap.xml/route.ts
import { createSitemapHandler } from '@djangocfg/nextjs/sitemap';
import { routing } from '@djangocfg/nextjs/i18n';

export const GET = createSitemapHandler({
  siteUrl: 'https://example.com',
  // i18n support with hreflang tags
  i18n: {
    locales: routing.locales,
    defaultLocale: routing.defaultLocale,
  },
  staticPages: [
    { loc: '/', changefreq: 'daily', priority: 1.0 },
    { loc: '/about', changefreq: 'monthly', priority: 0.8 },
  ],
  dynamicPages: async () => {
    const posts = await fetchPosts();
    return posts.map(post => ({
      loc: `/posts/${post.slug}`,
      lastmod: post.updatedAt,
      changefreq: 'weekly',
      priority: 0.7,
    }));
  },
});

Generated XML with hreflang:

<url>
  <loc>https://example.com/en/about</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en/about"/>
  <xhtml:link rel="alternate" hreflang="ru" href="https://example.com/ru/about"/>
  <xhtml:link rel="alternate" hreflang="ko" href="https://example.com/ko/about"/>
  <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/en/about"/>
  <changefreq>monthly</changefreq>
  <priority>0.8</priority>
</url>

Health Check Endpoint

Create a health monitoring endpoint:

// app/api/health/route.ts
import { createHealthHandler } from '@djangocfg/nextjs/health';

export const GET = createHealthHandler({
  version: process.env.NEXT_PUBLIC_APP_VERSION || '1.0.0',
  checks: [
    {
      name: 'database',
      check: async () => {
        // Check database connection
        return await checkDatabase();
      },
    },
  ],
});

OG Image Generation

Builds typed URLs pointing to Django's django_ogimage renderer — no Edge Runtime, no @vercel/og:

// app/page.tsx
import { withOgImage } from '@djangocfg/nextjs/og-image'

export async function generateMetadata(): Promise<Metadata> {
  return withOgImage(
    { title: 'My Page', description: 'Description' },
    { preset: 'DARK_BLUE', layout: 'HERO' }
  )
}

The URL is resolved automatically from NEXT_PUBLIC_MEDIA_URLNEXT_PUBLIC_API_URLNEXT_PUBLIC_SITE_URL. Django renders and caches the PNG — no Edge Runtime or @vercel/og required.

Navigation Utilities

Define routes and generate navigation menus:

import { defineRoute, routesToMenuItems } from '@djangocfg/nextjs/navigation';

const routes = [
  defineRoute('/dashboard', { title: 'Dashboard' }),
  defineRoute('/settings', { title: 'Settings' }),
];

const menuItems = routesToMenuItems(routes);

Client Components

Client-side components (legal pages, error pages, redirect components) are available in @djangocfg/layouts:

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

// Error pages
import { ErrorLayout } from '@djangocfg/layouts/components/errors';

// Redirect component
import { RedirectPage } from '@djangocfg/layouts/components/RedirectPage';

Exports

| Path | Description | |------|-------------| | @djangocfg/nextjs | Main exports (all modules) | | @djangocfg/nextjs/i18n | Types only (safe for server components) | | @djangocfg/nextjs/i18n/routing | routing, createRouting, generateLocaleParams, DEFAULT_LOCALES, DEFAULT_LOCALE | | @djangocfg/nextjs/i18n/client | I18nProvider, hooks ('use client') | | @djangocfg/nextjs/i18n/server | Server-side i18n utilities | | @djangocfg/nextjs/i18n/components | LocaleSwitcher ('use client') | | @djangocfg/nextjs/i18n/proxy | createProxy for middleware | | @djangocfg/nextjs/i18n/navigation | Link, redirect, usePathname, useRouter | | @djangocfg/nextjs/ai | AI documentation search and MCP config | | @djangocfg/nextjs/config | Base Next.js configuration factory | | @djangocfg/nextjs/pwa | PWA client utilities (service worker registration) | | @djangocfg/nextjs/pwa/worker | Service worker creation helpers | | @djangocfg/nextjs/sitemap | Sitemap generation with i18n hreflang support | | @djangocfg/nextjs/health | Health check handlers | | @djangocfg/nextjs/og-image | OG image URL builder for Django's django_ogimage renderer | | @djangocfg/nextjs/navigation | Route definitions, menu generation, navigation helpers |

API Reference

Base Configuration

createBaseNextConfig(options)

Creates a reusable base Next.js configuration with standard DjangoCFG settings.

createBaseNextConfig({
  basePath?: string;                    // Base path for static builds
  transpilePackages?: string[];          // Additional packages to transpile
  optimizePackageImports?: string[];     // Additional packages to optimize
  webpack?: (config, options) => config; // Custom webpack configuration
  experimental?: NextConfig['experimental']; // Custom experimental options
  env?: Record<string, string>;         // Custom environment variables
  // ... any other NextConfig options
})

Features:

  • Automatic dev/production optimizations
  • Filesystem caching for faster rebuilds
  • Compression plugins for static builds (Gzip + Brotli)
  • Standard transpile packages for monorepo
  • Type-safe configuration merging

i18n

Subpath imports required - see table below for correct import paths.

DEFAULT_LOCALES / DEFAULT_LOCALE

All 17 supported locales and the default locale constant.

import { DEFAULT_LOCALES, DEFAULT_LOCALE } from '@djangocfg/nextjs/i18n/routing';

DEFAULT_LOCALES  // ['en', 'ru', 'ko', 'ja', 'de', 'fr', 'zh', 'it', 'es', 'nl', 'ar', 'tr', 'pt-BR', 'pl', 'sv', 'no', 'da']
DEFAULT_LOCALE   // 'en'

Use in locales.config.ts to stay in sync with the package:

// i18n/locales.config.ts
export { DEFAULT_LOCALES as LOCALES, DEFAULT_LOCALE } from '@djangocfg/nextjs/i18n/routing';
export type { LocaleCode as AppLocale } from '@djangocfg/nextjs/i18n';

routing

Default routing configuration with all 17 locales and default locale 'en'.

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

routing.locales       // ['en', 'ru', 'ko', 'ja', ...]
routing.defaultLocale // 'en'

createRouting(config?)

Create custom routing configuration.

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

const routing = createRouting({
  locales: ['en', 'de', 'fr'],
  defaultLocale: 'en',
  localePrefix: 'always', // 'always' | 'as-needed' | 'never'
});

I18nProvider

Provider component for next-intl integration (client component).

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

<I18nProvider locale="en" messages={messages}>
  {children}
</I18nProvider>

LocaleSwitcher

Smart locale switcher that wraps @djangocfg/layouts LocaleSwitcher with next-intl hooks.

import { LocaleSwitcher } from '@djangocfg/nextjs/i18n/components';

// Automatically gets locale from next-intl routing
<LocaleSwitcher />

// With custom options
<LocaleSwitcher
  locales={['en', 'ru']}        // Override available locales
  labels={{ en: 'EN', ru: 'RU' }} // Custom locale labels
  variant="outline"
  size="sm"
  showIcon={true}
  className="w-full"
/>

Props (extends @djangocfg/layouts LocaleSwitcherProps): | Prop | Type | Default | Description | |------|------|---------|-------------| | locales | string[] | From routing | Override available locales | | labels | Record<string, string> | Built-in | Custom locale labels | | showCode | boolean | false | Show locale code with label | | variant | 'ghost' \| 'outline' \| 'default' | 'ghost' | Button variant | | size | 'sm' \| 'default' \| 'lg' \| 'icon' | 'sm' | Button size | | showIcon | boolean | true | Show globe icon |

Sitemap

createSitemapHandler(options)

Creates a Next.js route handler for sitemap generation with optional i18n support.

createSitemapHandler({
  siteUrl: string;
  staticPages?: SitemapUrl[];
  dynamicPages?: SitemapUrl[] | (() => Promise<SitemapUrl[]>);
  cacheControl?: string;
  // i18n support
  i18n?: {
    locales: string[];      // e.g., ['en', 'ru', 'ko']
    defaultLocale: string;  // e.g., 'en'
  };
})

When i18n is provided:

  • URLs are expanded for each locale (e.g., /about/en/about, /ru/about, /ko/about)
  • xhtml:link elements with hreflang are added for SEO
  • x-default points to the default locale

Health

createHealthHandler(config)

Creates a health check route handler.

createHealthHandler({
  version?: string;
  checks?: Array<{ name: string; check: () => Promise<boolean> }>;
  customData?: Record<string, any>;
})

OG Image

@djangocfg/nextjs/og-image builds typed URLs pointing to Django's django_ogimage renderer. No Edge Runtime, no @vercel/og, no JSX templates — Django renders and caches the PNG.

See src/og-image/README.md for full docs including URL resolution logic and deployment examples.

withOgImage(metadata, params)

Merges OG image into an existing Metadata object. Auto-extracts title if not in params.

import { withOgImage } from '@djangocfg/nextjs/og-image'

export async function generateMetadata(): Promise<Metadata> {
  return withOgImage(
    { title: 'My Page', description: 'Description' },
    { preset: 'DARK_BLUE', layout: 'HERO' }
  )
}

createOgMetadata(params)

Returns a Metadata fragment with openGraph.images + twitter.images.

import { createOgMetadata } from '@djangocfg/nextjs/og-image'

export async function generateMetadata() {
  return createOgMetadata({ title: 'Page', preset: 'DARK_BLUE' })
}

buildOgUrl(params)

Returns the raw URL string. Useful when you need the URL outside of metadata.

import { buildOgUrl } from '@djangocfg/nextjs/og-image'

const url = buildOgUrl({ title: 'Hello', preset: 'DARK_BLUE' })

URL resolution (NEXT_PUBLIC_MEDIA_URLNEXT_PUBLIC_API_URLNEXT_PUBLIC_SITE_URL → relative).

Navigation

defineRoute(path, metadata, config?)

Defines a route with metadata.

defineRoute('/dashboard', {
  title: 'Dashboard',
  description: 'Dashboard overview',
}, {
  basePath: '/admin',
  isStaticBuild: false,
})

isActive(current, target, allRoutes?)

Checks if a route is currently active.

isActive('/admin/dashboard', '/admin/dashboard') // true
isActive('/admin/dashboard/settings', '/admin/dashboard') // true
isActive('/admin/dashboard', '/admin/settings') // false

routesToMenuItems(routes)

Converts route definitions to menu items.

const menuItems = routesToMenuItems(allRoutes);

Requirements

  • Next.js >= 13.0.0 (App Router)
  • React >= 18.0.0
  • TypeScript >= 5.0.0

Peer Dependencies

  • next - Next.js framework (^15.5.7)

Documentation

Full documentation available at djangocfg.com

Contributing

Issues and pull requests are welcome at GitHub

License

MIT - see LICENSE for details