Next.js
Next.js is a modern full-stack development framework based on React, developed and maintained by the Vercel team. It provides out-of-the-box features including Server-Side Rendering (SSR), Static Site Generation (SSG), Incremental Static Regeneration (ISR), API routes, and file-system-based routing, enabling developers to rapidly build high-performance Web applications.
This guide details how to develop and deploy Next.js applications on CloudBase HTTP cloud functions, fully leveraging Next.js' full-stack capabilities.
Prerequisites
Before you begin, ensure you meet the following requirements:
- Node.js environment: version 18.18 or higher (20.x recommended)
- npm, yarn, or pnpm: package manager
- React Fundamentals: Familiar with React component development
- CloudBase account: with a Tencent Cloud account registered and TCB service activated
Environment Preparation
1. Check the Node.js version
# Check the Node.js version
node --version
# Check the npm version
npm --version
2. Create a Next.js application
If you already have a Next.js application, you can skip this step.
# Create a Next.js application using the official CLI
npx create-next-app@latest my-nextjs-app
# Go to the project directory
cd my-nextjs-app
Configuration options during the creation process:
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Recommended configuration:
- TypeScript: Yes (Better type safety)
- ESLint: Yes (Code quality assurance)
- Tailwind CSS: Yes (Rapid style development)
- App Router: Yes (Recommended for Next.js 13+)
Application Development
1. Project Structure
Project structure using App Router:
my-nextjs-app/
├── app/
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page
│ ├── api/ # API Routes
│ │ └── users/
│ │ └── route.ts # /api/users endpoint
│ └── about/
│ └── page.tsx # /about page
├── components/ # Reusable components
├── lib/ # Utility functions
├── public/ # Static resources
├── next.config.js # Next.js configuration
└── package.json
2. Configure Next.js
Edit the next.config.js file to optimize for CloudBase deployment:
/** @type {import('next').NextConfig} */
const nextConfig = {
// Set output mode to standalone for cloud function deployment
output: 'standalone',
// Disable x-powered-by header
poweredByHeader: false,
// Compression configuration
compress: true,
// Image optimization configuration
images: {
domains: ['example.com'], // Add external image domains
unoptimized: true, // Disable image optimization in cloud function environments
},
// Environment Variable Configuration
env: {
CUSTOM_KEY: process.env.CUSTOM_KEY,
},
// Redirect configuration
async redirects() {
return [
{
source: '/old-path',
destination: '/new-path',
permanent: true,
},
];
},
// Header configuration
async headers() {
return [
{
source: '/api/:path*',
headers: [
{
key: 'Access-Control-Allow-Origin',
value: '*',
},
{
key: 'Access-Control-Allow-Methods',
value: 'GET, POST, PUT, DELETE, OPTIONS',
},
{
key: 'Access-Control-Allow-Headers',
value: 'Content-Type, Authorization',
},
],
},
];
},
};
module.exports = nextConfig;
3. Create page component
Home Component
Edit app/page.tsx:
import Link from 'next/link';
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Next.js on CloudBase',
description: 'A Next.js application running on CloudBase HTTP Functions',
};
export default function HomePage() {
return (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
<div className="container mx-auto px-4 py-16">
<div className="text-center">
<h1 className="text-4xl font-bold text-gray-900 mb-6">
Welcome to Next.js on CloudBase
</h1>
<p className="text-xl text-gray-600 mb-8">
This is a Next.js application running on CloudBase HTTP cloud function.
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mt-12">
<FeatureCard
title="Server-Side Rendering"
description="Enjoy Next.js SSR capabilities to enhance SEO and improve first-screen loading speed"
icon="🚀"
/>
<FeatureCard
title="API Routes"
description="Built-in API Routes feature to easily build full-stack applications"
icon="⚡"
/>
<FeatureCard
title="Cloud-Native Deployment"
description="Deploy to CloudBase with one click to enjoy elastic scaling and high availability"
icon="☁️"
/>
</div>
<div className="mt-12 space-x-4">
<Link
href="/about"
className="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700 transition-colors"
>
Learn More
</Link>
<Link
href="/api/users"
className="bg-gray-600 text-white px-6 py-3 rounded-lg hover:bg-gray-700 transition-colors"
>
Test API
</Link>
</div>
</div>
</div>
</div>
);
}
interface FeatureCardProps {
title: string;
description: string;
icon: string;
}
function FeatureCard({ title, description, icon }: FeatureCardProps) {
return (
<div className="bg-white p-6 rounded-lg shadow-md">
<div className="text-3xl mb-4">{icon}</div>
<h3 className="text-xl font-semibold mb-2">{title}</h3>
<p className="text-gray-600">{description}</p>
</div>
);
}
About Page
Create app/about/page.tsx:
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'About Us - Next.js on CloudBase',
description: 'Learn more about Next.js and CloudBase',
};
export default function AboutPage() {
return (
<div className="min-h-screen bg-gray-50 py-16">
<div className="container mx-auto px-4">
<div className="max-w-4xl mx-auto">
<h1 className="text-3xl font-bold text-gray-900 mb-8">About Next.js on CloudBase</h1>
<div className="bg-white rounded-lg shadow-md p-8 mb-8">
<h2 className="text-2xl font-semibold mb-4">Tech Stack</h2>
<ul className="space-y-2 text-gray-700">
<li>• <strong>Next.js 14+</strong>: React full-stack framework</li>
<li>• <strong>TypeScript</strong>: Type-safe JavaScript</li>
<li>• <strong>Tailwind CSS</strong>: A utility-first CSS framework</li>
<li>• <strong>CloudBase</strong>: Tencent Cloud native application development platform</li>
</ul>
</div>
<div className="bg-white rounded-lg shadow-md p-8">
<h2 className="text-2xl font-semibold mb-4">Features</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h3 className="font-semibold mb-2">Frontend Features</h3>
<ul className="space-y-1 text-gray-700">
<li>• Server-Side Rendering (SSR)</li>
<li>• Static Site Generation (SSG)</li>
<li>• Incremental Static Regeneration (ISR)</li>
<li>• Automatic code splitting</li>
</ul>
</div>
<div>
<h3 className="font-semibold mb-2">Backend Features</h3>
<ul className="space-y-1 text-gray-700">
<li>• API Routing</li>
<li>• Middleware Support</li>
<li>• Database Integration</li>
<li>• Authentication</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
4. Creating API Routes
User API
Create app/api/users/route.ts:
import { NextRequest, NextResponse } from 'next/server';
// Mock user data
let users = [
{ id: 1, name: 'Alice Johnson', email: 'alice@example.com', role: 'admin' },
{ id: 2, name: 'Bob Smith', email: 'bob@example.com', role: 'user' },
{ id: 3, name: 'Charlie Brown', email: 'charlie@example.com', role: 'user' },
];
// GET /api/users - Obtain all users
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const role = searchParams.get('role');
let filteredUsers = users;
if (role) {
filteredUsers = users.filter(user => user.role === role);
}
return NextResponse.json({
success: true,
data: filteredUsers,
total: filteredUsers.length,
});
} catch (error) {
return NextResponse.json(
{ success: false, error: 'Failed to fetch users' },
{ status: 500 }
);
}
}
// POST /api/users - Creating a New User
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { name, email, role = 'user' } = body;
// Simple validation
if (!name || !email) {
return NextResponse.json(
{ success: false, error: 'Name and email are required' },
{ status: 400 }
);
}
// Check whether the email already exists
const existingUser = users.find(user => user.email === email);
if (existingUser) {
return NextResponse.json(
{ success: false, error: 'Email already exists' },
{ status: 409 }
);
}
const newUser = {
id: Math.max(...users.map(u => u.id), 0) + 1,
name,
email,
role,
};
users.push(newUser);
return NextResponse.json(
{ success: true, data: newUser },
{ status: 201 }
);
} catch (error) {
return NextResponse.json(
{ success: false, error: 'Failed to create user' },
{ status: 500 }
);
}
}
Health Check API
Create app/api/health/route.ts:
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: process.env.NODE_ENV || 'development',
version: process.env.npm_package_version || '1.0.0',
});
}
5. Add Middleware
Create middleware.ts (in the project root directory):
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Add security headers
const response = NextResponse.next();
response.headers.set('X-Frame-Options', 'DENY');
response.headers.set('X-Content-Type-Options', 'nosniff');
response.headers.set('Referrer-Policy', 'origin-when-cross-origin');
// CORS handling for API routing
if (request.nextUrl.pathname.startsWith('/api/')) {
response.headers.set('Access-Control-Allow-Origin', '*');
response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// Handle preflight requests
if (request.method === 'OPTIONS') {
return new Response(null, { status: 200, headers: response.headers });
}
}
return response;
}
export const config = {
matcher: [
'/((?!_next/static|_next/image|favicon.ico).*)',
],
};
Local Development
1. Install Dependencies
# Install project dependencies
npm install
# or use yarn
yarn install
# or use pnpm
pnpm install
2. Start up the development server
# Development Mode Startup
npm run dev
# Start up with specified port
npm run dev -- -p 9000
3. Test the Application
Access the following URL to test the application:
# Home Page
curl http://localhost:3000
# About Page
curl http://localhost:3000/about
# Health Check API
curl http://localhost:3000/api/health
# User API
curl http://localhost:3000/api/users
# Create a user.
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"name":"David Wilson","email":"david@example.com","role":"admin"}'
# Filter Users by Role
curl "http://localhost:3000/api/users?role=admin"
Deployment Configuration
1. Build the Application
# Build Production Version
npm run build
# Starting the Production Server (Local Testing)
npm start
2. Create the scf_bootstrap File
Create the scf_bootstrap file (without extension) in the project root directory:
#!/bin/sh
# Set the port to 9000 (CloudBase HTTP cloud function requirement)
export PORT=9000
# Set Node.js Environment to Production Mode
export NODE_ENV=production
# Start the Next.js Application
npm start
3. Set File Permissions
chmod +x scf_bootstrap
4. Optimize package.json
Ensure the package.json contains the correct script:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "14.0.0",
"react": "^18",
"react-dom": "^18"
}
}
5. Environment Variable Configuration
Create the .env.local file (for local development):
# Database Configuration
DATABASE_URL=your_database_url
# API Key
API_SECRET_KEY=your_secret_key
# External Service Configuration
EXTERNAL_API_URL=https://api.example.com
Deploy to CloudBase
Method 1: Console Deployment
Open the CloudBase console Access the Tencent Cloud CloudBase console
Create an HTTP cloud function
- Function Type: Select [HTTP cloud function]
- Function name: Input
nextjs-app(or custom name) - Submission method: Select [Local folder upload]
Configure deployment parameters
- Function code: Select your Next.js project root directory
- Runtime environment: Select
Node.js 20.19(recommended) orNode.js 18.15 - Automatic Dependency Installation: Enable
- Memory configuration: Recommended 512MB or higher
Complete deployment Click the "Create" button and wait for the deployment to complete.
Method 2: CLI Deployment (Coming Soon)
Accessing the Application
After successful deployment, you can refer to Accessing Cloud Functions via HTTP to configure custom domain access for
You can test the following APIs:
- Root Path:
/- Express Welcome Page - Health Check:
/health- View Application Status
Performance Optimization
1. Code Splitting
// Dynamically import components
import dynamic from 'next/dynamic';
const DynamicComponent = dynamic(() => import('../components/HeavyComponent'), {
loading: () => <p>Loading...</p>,
ssr: false, // Disable server-side rendering
});
export default function Page() {
return (
<div>
<DynamicComponent />
</div>
);
}
2. Image Optimization
import Image from 'next/image';
export default function OptimizedImage() {
return (
<Image
src="/hero-image.jpg"
alt="Hero Image"
width={800}
height={600}
priority // Load with priority
placeholder="blur" // Blur placeholder
blurDataURL="data:image/jpeg;base64,..." // placeholder data
/>
);
}
3. Cache Policy
// app/api/data/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
const data = await fetchData();
return NextResponse.json(data, {
headers: {
'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=300',
},
});
}
Best Practices
1. Error Handling
Create app/error.tsx:
'use client';
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<h2 className="text-2xl font-bold mb-4">Error occurred!</h2>
<p className="text-gray-600 mb-4">{error.message}</p>
<button
onClick={reset}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
>
Retry
</button>
</div>
</div>
);
}
2. Loading State
Create app/loading.tsx:
export default function Loading() {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="animate-spin rounded-full h-32 w-32 border-b-2 border-blue-600"></div>
</div>
);
}
3. 404 Page
Create app/not-found.tsx:
import Link from 'next/link';
export default function NotFound() {
return (
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<h1 className="text-6xl font-bold text-gray-900 mb-4">404</h1>
<h2 className="text-2xl font-semibold mb-4">Page Not Found</h2>
<p className="text-gray-600 mb-8">Sorry, the page you visited does not exist.</p>
<Link
href="/"
className="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700 transition-colors"
>
Back to Home
</Link>
</div>
</div>
);
}
Frequently Asked Questions
Q: Page styles not loading after deployment?
A: Check the following points:
- Confirm the
output: 'standalone'configuration innext.config.js - Check if the static resource path is correct
- Verify whether the CSS files are properly bundled
Q: API route returns 404 error?
A: Common causes:
- Check whether the API route file is named
route.tsorroute.js - Confirm the file location is in the
app/api/directory - Verify whether the HTTP methods are properly exported
Q: Application start-up is slow?
A: Optimization recommendations:
- Use
output: 'standalone'to reduce bundle size - Enable code splitting and lazy loading
- Optimize images and static resources
- Consider using ISR or SSG
Q: How do I connect to the database?
A: It is recommended to use CloudBase database or other cloud databases:
// lib/database.ts
import { MongoClient } from 'mongodb';
const client = new MongoClient(process.env.DATABASE_URL!);
export async function connectToDatabase() {
if (!client.topology?.isConnected()) {
await client.connect();
}
return client.db('nextjs_app');
}
// app/api/users/route.ts
import { connectToDatabase } from '@/lib/database';
export async function GET() {
const db = await connectToDatabase();
const users = await db.collection('users').find({}).toArray();
return NextResponse.json({ data: users });
}
Q: How do I handle environment variables?
A: Configure environment variables in the CloudBase console, or use the .env file:
// Use environment variables in components
const apiUrl = process.env.NEXT_PUBLIC_API_URL; // Accessible on the client side
const secretKey = process.env.SECRET_KEY; // Accessible only on the server side
Summary
Through this guide, you have learned how to develop and deploy Next.js applications on CloudBase HTTP cloud functions. The full-stack capabilities of Next.js combined with CloudBase's cloud-native features can help you rapidly build modern Web applications.
It is recommended to further optimize application performance, add database integration, and implement authentication features based on business requirements in actual projects to fully leverage the advantages of Next.js and CloudBase.