@djangocfg/ext-base
Base utilities and common code for building DjangoCFG extensions.
Part of DjangoCFG — modern Django framework for production-ready SaaS applications.
What is this?
@djangocfg/ext-base provides the foundation for DjangoCFG extensions with:
- Extension registration system and metadata tracking
- React hooks for pagination, infinite scroll, and data fetching
- Environment utilities (isDevelopment, isProduction, isStaticBuild)
- Type-safe context helpers and logger utilities
- Auth integration and API factory
- CLI tool for managing extensions
Used internally by official extensions (newsletter, payments, support, leads, knowbase) and for building custom extensions.
Install
pnpm add @djangocfg/ext-base
CLI Usage
The package includes a CLI tool for managing DjangoCFG extensions:
djangocfg-ext list
djangocfg-ext info ext-leads
djangocfg-ext install
djangocfg-ext init
djangocfg-ext help
Available Extensions
- @djangocfg/ext-leads - Lead management and contact forms
- @djangocfg/ext-payments - Payment processing with multiple providers
- @djangocfg/ext-newsletter - Newsletter and email campaigns
- @djangocfg/ext-support - Customer support and ticketing
- @djangocfg/ext-knowbase - Knowledge base and documentation
Quick Start
1. Create extension metadata
import type { ExtensionMetadata } from '@djangocfg/ext-base';
export const extensionConfig: ExtensionMetadata = {
name: 'my-extension',
version: '1.0.0',
displayName: 'My Extension',
description: 'Amazing extension functionality',
icon: '🚀',
};
2. Create extension provider
'use client';
import { ExtensionProvider } from '@djangocfg/ext-base/hooks';
import { extensionConfig } from '../config';
export function MyExtensionProvider({ children }) {
return (
<ExtensionProvider metadata={extensionConfig}>
{children}
</ExtensionProvider>
);
}
3. Use in your app
import { MyExtensionProvider } from '@your-org/my-extension/hooks';
export default function RootLayout({ children }) {
return (
<MyExtensionProvider>
{children}
</MyExtensionProvider>
);
}
Core Features
Environment Configuration
import { isDevelopment, isProduction, isStaticBuild } from '@djangocfg/ext-base';
if (isDevelopment) {
console.log('Running in development mode');
}
API Factory
Create extension API instances with automatic configuration:
import { API } from './generated/ext_myextension';
import { createExtensionAPI } from '@djangocfg/ext-base/api';
export const apiMyExtension = createExtensionAPI(API);
import { usePagination, useInfinitePagination } from '@djangocfg/ext-base/hooks';
const { items, page, totalPages, goToPage, nextPage, prevPage } = usePagination({
keyPrefix: 'articles',
fetcher: async (page, pageSize) => {
const response = await api.articles.list({ page, page_size: pageSize });
return response.data;
},
pageSize: 20,
});
const { items, isLoading, hasMore, loadMore } = useInfinitePagination({
keyPrefix: 'articles',
fetcher: async (page, pageSize) => api.articles.list({ page, page_size: pageSize }).then(r => r.data),
pageSize: 20,
});
Type-Safe Context Creation
import { createExtensionContext } from '@djangocfg/ext-base/hooks';
interface MyContextValue {
data: any[];
refresh: () => void;
}
const { Provider, useContext: useMyContext } = createExtensionContext<MyContextValue>({
displayName: 'MyContext',
errorMessage: 'useMyContext must be used within MyProvider',
});
Logger
import { createExtensionLogger } from '@djangocfg/ext-base';
const logger = createExtensionLogger({ tag: 'my-extension' });
logger.info('Extension initialized');
logger.error('Operation failed', error);
logger.success('Completed!');
Auth Integration
import { useAuth } from '@djangocfg/ext-base/auth';
function MyComponent() {
const { user, isAuthenticated, login, logout } = useAuth();
return isAuthenticated ? (
<div>Welcome, {user?.email}</div>
) : (
<button onClick={login}>Login</button>
);
}
Package Exports
@djangocfg/ext-base | Server-safe exports (types, environment, API factory, logger, error handling) | Server & client components |
@djangocfg/ext-base/hooks | Client-only exports (ExtensionProvider, pagination hooks, context factory) | Client components only |
@djangocfg/ext-base/auth | Auth re-exports (useAuth, types) | Client components only |
@djangocfg/ext-base/api | API utilities (createExtensionAPI, getSharedAuthStorage) | Server & client components |
TypeScript Types
import type {
ExtensionMetadata,
ExtensionProviderProps,
PaginatedResponse,
PaginationParams,
PaginationState,
InfinitePaginationReturn,
ExtensionLogger,
ExtensionError,
} from '@djangocfg/ext-base';
Best Practices
- Always wrap your extension with
ExtensionProvider for proper registration
- Define complete metadata in
config.ts
- Use provided pagination hooks for consistent data fetching
- Use
createExtensionLogger with consistent tags for structured logging
- Separate client-only code using
/hooks entry point
License
MIT
Links