Deploy Next.js
Deploy a Next.js application to Espace-Tech Cloud.
Prerequisites
- Next.js 13+ (App Router or Pages Router)
- Node.js 18+
- Espace-Tech CLI installed
1. Initialize
cd my-nextjs-app
espacetech initAuto-detected espacetech.json:
{
"name": "my-nextjs-app",
"framework": "nextjs",
"build_command": "npm run build",
"start_command": "npm start",
"port": 3000
}2. Configure for Standalone Output
For optimal performance, enable standalone output in next.config.ts:
next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "standalone",
};
export default nextConfig;This creates a minimal production build without unnecessary node_modules.
3. Deploy
espacetech deployYour app will be live at my-nextjs-app.app.espace-tech.com.
Environment Variables
Set environment variables before or after deploy:
espacetech env set DATABASE_URL=postgres://... NEXT_PUBLIC_API_URL=https://api.example.comVariables prefixed with NEXT_PUBLIC_ are embedded at build time. Set them before deploying.
Using the SDK
Install the Espace-Tech SDK for storage, auth, and database access:
npm install github:bz-reda/Espace-Tech-Cloud-SDKlib/espace.ts
import { EspaceTech } from "@espace-tech/sdk";
export const espace = new EspaceTech({
apiToken: process.env.ESPACE_TECH_TOKEN!,
});Storage (Server Components / API Routes)
app/api/upload/route.ts
import { espace } from "@/lib/espace";
export async function POST(req: Request) {
const formData = await req.formData();
const file = formData.get("file") as File;
await espace.storage.upload("bucket-id", `uploads/${file.name}`, file);
return Response.json({ success: true });
}Auth (Middleware)
app/api/protected/route.ts
import { espace } from "@/lib/espace";
export async function GET(req: Request) {
const token = req.headers.get("authorization")?.replace("Bearer ", "");
if (!token) return Response.json({ error: "Unauthorized" }, { status: 401 });
const user = await espace.auth.verifyToken("auth-app-id", token);
if (!user.valid) return Response.json({ error: "Invalid token" }, { status: 401 });
return Response.json({ user });
}Database
import { espace } from "@/lib/espace";
import { Pool } from "pg";
const conn = await espace.database.getConnection("db-id");
const pool = new Pool({ connectionString: conn.url });Serving Images with Presigned URLs
next.config.ts
const nextConfig: NextConfig = {
output: "standalone",
images: {
remotePatterns: [
{ protocol: "https", hostname: "s3.espace-tech.com" },
],
},
};app/api/images/route.ts
import { espace } from "@/lib/espace";
export async function GET() {
const result = await espace.storage.listObjects("bucket-id", { prefix: "images/" });
const images = await Promise.all(
result.objects
.filter((obj) => !obj.is_folder)
.map(async (obj) => ({
key: obj.key,
url: (await espace.storage.getDownloadUrl("bucket-id", obj.key)).url,
}))
);
return Response.json({ images });
// Use directly: <Image src={image.url} />
}Custom Domain
espacetech domains add my-app.comAdd an A record pointing my-app.com to 65.109.68.181. SSL is automatic.