nextjs-django-client
TypeScript icon, indicating that this package has built-in type declarations

2.7.0 • Public • Published

Next.js Django Client SDK

🚀 The easiest way to connect your Next.js app to Django REST Framework

A comprehensive, type-safe SDK that makes integrating Next.js applications with Django backends simple and powerful. Perfect for beginners and experts alike!

✨ Why Choose This SDK?

  • 🎯 Beginner-Friendly: Get started in minutes with our step-by-step guide
  • 🔒 Secure by Default: Built-in JWT authentication and CSRF protection
  • 📝 Full TypeScript: Complete type safety for your API calls
  • 🤖 Auto-Generated Code: Generate API clients from your OpenAPI specs
  • Modern React: Built for Next.js 15+ with React 18+ hooks
  • 🧪 Well Tested: Comprehensive test suite with 95%+ coverage

🚀 Quick Start (5 minutes)

Step 1: Install the Package

npm install nextjs-django-client
# or
yarn add nextjs-django-client
# or
pnpm add nextjs-django-client

Bundle Options

Choose the right bundle for your needs:

// Full bundle (258 KB) - All features included
import { createDjangoApiClient, useAuth, useRBAC } from 'nextjs-django-client';

// Core bundle (136 KB) - Basic features only (recommended for most users)
import { createDjangoApiClient, useAuth } from 'nextjs-django-client/core';

// Advanced bundle (171 KB) - RBAC, social login, advanced auth
import { useRBAC, useSocialLogin, AdvancedAuthProvider } from 'nextjs-django-client/advanced';

Step 2: Create Your API Client

Create a new file lib/api.ts in your Next.js project:

import { createDjangoApiClient } from 'nextjs-django-client';

// Replace with your Django API URL
export const apiClient = createDjangoApiClient('http://localhost:8000/api');

Step 3: Add Authentication (Optional)

Wrap your app with the AuthProvider in app/layout.tsx or pages/_app.tsx:

import { AuthProvider } from 'nextjs-django-client';
import { apiClient } from '@/lib/api';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <AuthProvider apiClient={apiClient}>
          {children}
        </AuthProvider>
      </body>
    </html>
  );
}

### Step 4: Start Making API Calls

Now you can use the API client anywhere in your app:

```tsx
'use client'; // For Next.js 13+ App Router

import { useState, useEffect } from 'react';
import { apiClient } from '@/lib/api';

interface User {
  id: number;
  email: string;
  name: string;
}

export default function UsersPage() {
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    async function fetchUsers() {
      try {
        const response = await apiClient.get<User[]>('/users/');
        setUsers(response);
      } catch (error) {
        console.error('Failed to fetch users:', error);
      } finally {
        setLoading(false);
      }
    }

    fetchUsers();
  }, []);

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name} ({user.email})</li>
        ))}
      </ul>
    </div>
  );
}

🔐 Authentication Made Easy

Simple Login Form

'use client';

import { useAuth } from 'nextjs-django-client';

export default function LoginForm() {
  const { login, isLoading, error } = useAuth();

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);

    await login({
      email: formData.get('email') as string,
      password: formData.get('password') as string,
    });
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div>
        <label htmlFor="email">Email:</label>
        <input
          id="email"
          name="email"
          type="email"
          required
          className="border rounded px-3 py-2"
        />
      </div>
      <div>
        <label htmlFor="password">Password:</label>
        <input
          id="password"
          name="password"
          type="password"
          required
          className="border rounded px-3 py-2"
        />
      </div>
      {error && <p className="text-red-500">{error.message}</p>}
      <button
        type="submit"
        disabled={isLoading}
        className="bg-blue-500 text-white px-4 py-2 rounded disabled:opacity-50"
      >
        {isLoading ? 'Logging in...' : 'Login'}
      </button>
    </form>
  );
}

Protected Routes

'use client';

import { useAuth } from 'nextjs-django-client';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';

export default function ProtectedPage() {
  const { user, isLoading, error } = useAuth(); // error property available for error handling
  const router = useRouter();

  useEffect(() => {
    if (!isLoading && !user) {
      router.push('/login');
    }
  }, [user, isLoading, router]);

  if (isLoading) return <div>Loading...</div>;
  if (!user) return null;

  return (
    <div>
      <h1>Welcome, {user.name}!</h1>
      <p>This is a protected page.</p>
    </div>
  );
}

🤖 Auto-Generate Your API Client (Recommended!)

The easiest way to get started is by generating your API client from your Django OpenAPI schema. This gives you:

  • 100% Type Safety: All your API endpoints are fully typed
  • Auto-completion: Your IDE knows all available methods and parameters
  • Always Up-to-date: Regenerate when your API changes
  • Zero Boilerplate: No manual API client code to write

Step 1: Export Your Django OpenAPI Schema

First, make sure your Django project exports an OpenAPI schema. Add this to your Django urls.py:

# urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.schemas import get_schema_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('your_app.urls')),
    # Add this line to export your schema
    path('api/schema/', get_schema_view(
        title="Your API",
        description="API for your awesome project",
        version="1.0.0"
    ), name='openapi-schema'),
]

Step 2: Generate Your API Client

# Download your schema (replace with your URL)
curl http://localhost:8000/api/schema/ > openapi.json

# Generate your API client
npx nextjs-django-codegen generate -i openapi.json -o src/generated

Step 3: Use Your Generated Client

// src/generated/index.ts is automatically created
import { GeneratedApiClient, useGetUsers, useCreateUser } from '@/generated';

// Create your client instance
const client = new GeneratedApiClient('http://localhost:8000/api');

// Use in React components with generated hooks
export default function UsersPage() {
  const { data: users, isLoading, error } = useGetUsers();
  const createUser = useCreateUser();

  const handleCreateUser = async () => {
    await createUser.mutateAsync({
      name: 'John Doe',
      email: 'john@example.com'
    });
  };

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h1>Users</h1>
      <button onClick={handleCreateUser}>Add User</button>
      <ul>
        {users?.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

Configuration File (Optional)

Create openapi.config.js for custom settings:

module.exports = {
  input: './openapi.json',
  output: './src/generated',
  generateTypes: true,
  generateClient: true,
  generateHooks: true,
  clientName: 'GeneratedApiClient', // Default changed to avoid naming conflicts
  prettier: true,
};

📚 Manual Configuration (Advanced)

If you prefer manual setup or need custom configuration:

Authentication Configuration

import { configureAuth } from 'nextjs-django-client';

const authConfig = configureAuth({
  loginEndpoint: '/api/auth/login/',
  refreshEndpoint: '/api/auth/refresh/',
  userEndpoint: '/api/auth/user/',
  useEmailAsUsername: true,
  secureTokens: true,
});

API Client Configuration

import { createApiClient } from 'nextjs-django-client';

const apiClient = createApiClient({
  baseURL: 'https://api.example.com',
  timeout: 30000,
  defaultHeaders: {
    'Content-Type': 'application/json',
  },
  retries: 3,
  retryDelay: 1000,
});

TypeScript Support

The SDK is built with TypeScript-first approach:

interface CustomUser extends User {
  customField: string;
}

// Type-safe authentication
const { user } = useAuth<CustomUser>();

// Type-safe API calls
const response = await apiClient.get<CustomUser[]>('/users/');

🚀 Production Ready

Bundle Optimization

Choose the right bundle for your needs to minimize bundle size:

  • Core Bundle (136 KB): Basic HTTP client, authentication, and OpenAPI generation
  • Advanced Bundle (171 KB): RBAC, social login, and advanced authentication features
  • Full Bundle (259 KB): All features included

Browser Compatibility

  • No Node.js dependencies in browser bundles
  • Tree-shakeable exports for optimal bundle size
  • ES2022+ target for modern browsers
  • Separate CLI bundle with Node.js dependencies

Testing

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch

Development

# Install dependencies
npm install

# Start development build
npm run dev

# Run linting
npm run lint

# Format code
npm run format

# Type checking
npm run type-check

Project Structure

src/
├── auth/                 # Authentication system
│   ├── providers/        # React context providers
│   ├── hooks/           # Authentication hooks
│   ├── types/           # TypeScript types
│   └── utils/           # Auth utilities
├── client/              # HTTP client
│   ├── http/            # Core HTTP client
│   ├── interceptors/    # Request/response interceptors
│   └── types/           # HTTP client types
├── state/               # State management (coming soon)
├── hooks/               # React hooks
├── utils/               # Utility functions
└── types/               # Global TypeScript types

Roadmap

Sprint 2 (Weeks 3-4)

  • JWT auto-refresh mechanism
  • Enhanced useAuth hook with auto-refresh
  • Secure cookie handling improvements

Sprint 3 (Weeks 5-6)

  • Customizable authentication endpoints
  • Role-based access control (RBAC)
  • Social login providers

Sprint 4 (Weeks 7-8)

  • Advanced state management with optimistic updates
  • Tag-based cache invalidation
  • Batch mutations

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Ensure all tests pass and coverage is maintained
  5. Submit a pull request

🚨 Troubleshooting

Common Issues and Solutions

1. CORS Errors

# In your Django settings.py
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",  # Your Next.js dev server
    "https://yourdomain.com",  # Your production domain
]

CORS_ALLOW_CREDENTIALS = True

2. Authentication Token Issues

// Check if token is being sent
apiClient.addInterceptor({
  request: (config) => {
    console.log('Headers:', config.headers);
    return config;
  }
});

3. TypeScript Errors with Generated Code

# Regenerate your API client
npx nextjs-django-codegen generate -i openapi.json -o src/generated

# Make sure your OpenAPI schema is valid
npx nextjs-django-codegen validate -i openapi.json

4. Network Errors in Development

// Use the correct Django dev server URL
const apiClient = createDjangoApiClient('http://127.0.0.1:8000/api');
// Not localhost if you're having issues

Getting Help

🤝 Contributing

We love contributions! Here's how you can help:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and add tests
  4. Run tests: npm test
  5. Submit a pull request

See our Contributing Guide for detailed instructions.

📄 License

MIT License - see LICENSE file for details.


Made with ❤️ for the Django + Next.js community

Package Sidebar

Install

npm i nextjs-django-client

Weekly Downloads

46

Version

2.7.0

License

MIT

Unpacked Size

16.2 MB

Total Files

19

Last publish

Collaborators

  • ats24