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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@djangocfg/nextjs

v2.1.49

Published

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

Readme

@djangocfg/nextjs

Server-side Next.js utilities: sitemap generation, health checks, OG images, 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. This package focuses on server-only functionality: SEO optimization with sitemaps, health monitoring, dynamic OG images, navigation utilities, and configuration management.

Note: Client components (legal pages, error pages, redirect components) have been moved to @djangocfg/layouts to keep this package server-only.

Features

  • Dev Server with Browser Auto-Open - Cross-platform CLI that works with Turbopack and webpack
  • Zero-Config PWA - Progressive Web App out of the box (service worker, offline support, manifest)
  • Base Next.js Config - Universal, reusable Next.js configuration factory for monorepos
  • AI Documentation - Search DjangoCFG docs via MCP server and CLI
  • Sitemap Generation - Dynamic XML sitemap generation for SEO
  • Health Checks - Production-ready health monitoring endpoints
  • OG Images - Dynamic Open Graph image generation with templates
  • Navigation Utilities - Route definitions, menu generation, and navigation helpers
  • TypeScript - Full type safety throughout
  • Server-Only - No client-side code, pure server utilities

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.

Push Notifications

Zero-config push notifications using standard Web Push Protocol (no Firebase needed).

PWA CLI

Quick commands for managing push notifications:

# Generate VAPID keys
pnpm pwa vapid

# Check PWA status
pnpm pwa status

# Send test push
pnpm pwa send '<subscription-json>'

# Show help
pnpm pwa info

1. Generate VAPID keys

pnpm pwa vapid

Add to .env.local:

NEXT_PUBLIC_VAPID_PUBLIC_KEY=your_public_key_here
VAPID_PRIVATE_KEY=your_private_key_here
VAPID_MAILTO=mailto:[email protected]

2. Add API routes

// app/api/push/subscribe/route.ts
export { POST, GET } from '@djangocfg/nextjs/pwa/server/routes';

// app/api/push/send/route.ts
export { handleSend as POST } from '@djangocfg/nextjs/pwa/server/routes';

3. Enable push in service worker

// app/sw.ts
import { createServiceWorker } from '@djangocfg/nextjs/pwa/worker';
import { settings } from '@core/settings';

createServiceWorker({
  offlineFallback: '/_offline',
  enablePushNotifications: true,
  notificationIcon: settings.app.icons.logo192,
  notificationBadge: settings.app.icons.logo192,
});

4. Subscribe from client

import { subscribeToPushNotifications } from '@djangocfg/nextjs/pwa';

const subscription = await subscribeToPushNotifications({
  vapidPublicKey: process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
});

// Save subscription to server
await fetch('/api/push/subscribe', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(subscription),
});

Testing with CLI

# 1. Start dev server
pnpm dev

# 2. Open browser console at http://localhost:3000
# 3. Subscribe to push notifications:
await (async () => {
  const { subscribeToPushNotifications } = await import('@djangocfg/nextjs/pwa');
  const sub = await subscribeToPushNotifications({
    vapidPublicKey: 'YOUR_PUBLIC_KEY'
  });
  await fetch('/api/push/subscribe', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(sub)
  });
  console.log('Subscribed!', sub);
})();

# 4. Send test notification (from another console tab or curl):
fetch('/api/push/send', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    subscription: { /* paste subscription object */ },
    notification: {
      title: 'Test Push',
      body: 'Hello from CLI!',
      icon: '/static/logos/192x192.png'
    }
  })
});

Or use curl:

curl -X POST http://localhost:3000/api/push/send \
  -H "Content-Type: application/json" \
  -d '{
    "subscription": {...},
    "notification": {
      "title": "Test",
      "body": "Hello!"
    }
  }'

Features:

  • Standard Web Push Protocol (VAPID)
  • No Firebase or external services required
  • Auto-configuration with helpful warnings
  • Ready-to-use route handlers
  • Built-in subscription management

Sitemap Generation

Generate dynamic XML sitemaps for SEO:

// app/sitemap.ts
import { createSitemapHandler } from '@djangocfg/nextjs/sitemap';

export default createSitemapHandler({
  siteUrl: 'https://example.com',
  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,
    }));
  },
});

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

Generate dynamic Open Graph images with custom templates:

// app/api/og/route.tsx
import { createOgImageHandler } from '@djangocfg/nextjs/og-image';
import { OgImageTemplate } from '@/components/OgImageTemplate';

export const runtime = 'edge';

const handler = createOgImageHandler({
  template: OgImageTemplate,
  defaultProps: {
    siteName: 'My App',
    logo: '/logo.svg',
  },
  fonts: [
    { family: 'Manrope', weight: 700 },
    { family: 'Manrope', weight: 500 },
  ],
  size: { width: 1200, height: 630 },
});

export async function GET(request: NextRequest) {
  return handler.GET(request);
}

Automatically add OG images to page metadata:

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

export const metadata = generateOgImageMetadata({
  title: 'My Page',
  description: 'Page description',
});

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/ai | AI documentation search and MCP config | | @djangocfg/nextjs/config | Base Next.js configuration factory | | @djangocfg/nextjs/pwa | PWA client utilities (service worker registration, push subscriptions) | | @djangocfg/nextjs/pwa/worker | Service worker creation helpers | | @djangocfg/nextjs/pwa/server | Server-side push notification utilities | | @djangocfg/nextjs/pwa/server/routes | Ready-to-use API route handlers for push | | @djangocfg/nextjs/sitemap | Sitemap generation utilities | | @djangocfg/nextjs/health | Health check handlers | | @djangocfg/nextjs/og-image | OG image generation | | @djangocfg/nextjs/og-image/utils | OG image URL and metadata utilities | | @djangocfg/nextjs/og-image/components | OG image template components | | @djangocfg/nextjs/navigation | Route definitions, menu generation, navigation helpers | | @djangocfg/nextjs/scripts | Utility scripts (e.g., link checking) |

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

Sitemap

createSitemapHandler(options)

Creates a Next.js route handler for sitemap generation.

createSitemapHandler({
  siteUrl: string;
  staticPages?: SitemapUrl[];
  dynamicPages?: SitemapUrl[] | (() => Promise<SitemapUrl[]>);
  cacheControl?: string;
})

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

createOgImageHandler(config)

Creates an OG image generation handler with custom template component.

createOgImageHandler({
  template: (props: OgImageTemplateProps) => ReactElement; // Template component
  defaultProps?: Partial<OgImageTemplateProps>;            // Default props
  fonts?: Array<{ family: string; weight: number }>;       // Google Fonts to load
  size?: { width: number; height: number };                 // Image dimensions
  debug?: boolean;                                          // Enable debug mode
})

generateOgImageMetadata(metadata, params?, options?)

Automatically adds OG image to Next.js metadata.

generateOgImageMetadata(
  metadata: Metadata,                    // Base metadata
  ogImageParams?: Partial<OgImageUrlParams>, // Optional explicit params
  options?: {
    ogImageBaseUrl?: string;             // Default: '/api/og'
    siteUrl?: string;                    // Auto-detected if not provided
    defaultParams?: Partial<OgImageUrlParams>; // Default params
    useBase64?: boolean;                  // Default: true
  }
)

generateOgImageUrl(baseUrl, params, useBase64?)

Note: This utility has been moved to @djangocfg/layouts/utils/og-image for client-side usage.

For server-side usage, you can still use it from @djangocfg/nextjs/og-image/utils, but for client components, import from layouts:

// Client component
import { generateOgImageUrl } from '@djangocfg/layouts/utils/og-image';

const url = generateOgImageUrl('/api/og', {
  title: 'My Page',
  description: 'Page description',
  siteName: 'My Site',
});

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