netlify-functions

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Netlify Functions

Netlify Functions

Modern Syntax

现代语法

Always use the modern default export + Config pattern. Never use the legacy
exports.handler
or named
handler
export.
typescript
import type { Context, Config } from "@netlify/functions";

export default async (req: Request, context: Context) => {
  return new Response("Hello, world!");
};

export const config: Config = {
  path: "/api/hello",
};
The handler receives a standard Web API
Request
and returns a
Response
. The second argument is a Netlify
Context
object.
始终使用现代的默认导出 + Config模式,禁止使用旧版的
exports.handler
或命名
handler
导出。
typescript
import type { Context, Config } from "@netlify/functions";

export default async (req: Request, context: Context) => {
  return new Response("Hello, world!");
};

export const config: Config = {
  path: "/api/hello",
};
handler接收标准Web API
Request
对象并返回
Response
对象,第二个参数为Netlify
Context
对象。

File Structure

文件结构

Place functions in
netlify/functions/
:
netlify/functions/
  _shared/           # Non-function shared code (underscore prefix)
    auth.ts
    db.ts
  items.ts           # -> /.netlify/functions/items (or custom path via config)
  users/index.ts     # -> /.netlify/functions/users
Use
.ts
or
.mts
extensions. If both
.ts
and
.js
exist with the same name, the
.js
file takes precedence.
将函数放在
netlify/functions/
目录下:
netlify/functions/
  _shared/           # 非函数类共享代码(下划线前缀)
    auth.ts
    db.ts
  items.ts           # -> /.netlify/functions/items(或通过config配置自定义路径)
  users/index.ts     # -> /.netlify/functions/users
使用
.ts
.mts
后缀,若存在同名的
.ts
.js
文件,
.js
文件优先级更高。

Path Routing

路径路由

Define custom paths via the
config
export:
typescript
export const config: Config = {
  path: "/api/items",                    // Static path
  // path: "/api/items/:id",            // Path parameter
  // path: ["/api/items", "/api/items/:id"], // Multiple paths
  // excludedPath: "/api/items/special", // Excluded paths
  // preferStatic: true,                // Don't override static files
};
Without a
path
config, functions are available at
/.netlify/functions/{name}
. Setting a
path
makes the function available only at that path.
Access path parameters via
context.params
:
typescript
// config: { path: "/api/items/:id" }
export default async (req: Request, context: Context) => {
  const { id } = context.params;
  // ...
};
通过导出的
config
定义自定义路径:
typescript
export const config: Config = {
  path: "/api/items",                    // 静态路径
  // path: "/api/items/:id",            // 路径参数
  // path: ["/api/items", "/api/items/:id"], // 多路径配置
  // excludedPath: "/api/items/special", // 排除路径
  // preferStatic: true,                // 不覆盖静态文件
};
未配置
path
时,函数的访问地址为
/.netlify/functions/{函数名}
;设置
path
后,函数可通过该路径访问。
通过
context.params
获取路径参数:
typescript
// config: { path: "/api/items/:id" }
export default async (req: Request, context: Context) => {
  const { id } = context.params;
  // ...
};

Method Routing

请求方法路由

typescript
export default async (req: Request, context: Context) => {
  switch (req.method) {
    case "GET":    return handleGet(context.params.id);
    case "POST":   return handlePost(await req.json());
    case "DELETE": return handleDelete(context.params.id);
    default:       return new Response("Method not allowed", { status: 405 });
  }
};

export const config: Config = {
  path: "/api/items/:id",
  method: ["GET", "POST", "DELETE"],
};
typescript
export default async (req: Request, context: Context) => {
  switch (req.method) {
    case "GET":    return handleGet(context.params.id);
    case "POST":   return handlePost(await req.json());
    case "DELETE": return handleDelete(context.params.id);
    default:       return new Response("Method not allowed", { status: 405 });
  }
};

export const config: Config = {
  path: "/api/items/:id",
  method: ["GET", "POST", "DELETE"],
};

Background Functions

后台函数

For long-running tasks (up to 15 minutes). The client receives an immediate
202
response; return values are ignored.
Name the file with a
-background
suffix:
netlify/functions/process-background.ts
Store results externally (Netlify Blobs, database) for later retrieval.
用于运行长时任务(最长15分钟),客户端会立即收到
202
响应,函数返回值会被忽略。
文件名使用
-background
后缀:
netlify/functions/process-background.ts
请将结果存储在外部服务(Netlify Blobs、数据库)中供后续查询。

Scheduled Functions

定时函数

Run on a cron schedule (UTC timezone):
typescript
export default async (req: Request) => {
  const { next_run } = await req.json();
  console.log("Next invocation at:", next_run);
};

export const config: Config = {
  schedule: "@hourly", // or cron: "0 * * * *"
};
Shortcuts:
@yearly
,
@monthly
,
@weekly
,
@daily
,
@hourly
. Scheduled functions have a 30-second timeout and only run on published deploys.
按cron表达式定时运行(时区为UTC):
typescript
export default async (req: Request) => {
  const { next_run } = await req.json();
  console.log("Next invocation at:", next_run);
};

export const config: Config = {
  schedule: "@hourly", // 或cron表达式: "0 * * * *"
};
快捷表达式:
@yearly
@monthly
@weekly
@daily
@hourly
。定时函数超时时间为30秒,且仅在已发布的部署版本中运行。

Streaming Responses

流式响应

Return a
ReadableStream
body for streamed responses (up to 20 MB):
typescript
export default async (req: Request) => {
  const stream = new ReadableStream({ /* ... */ });
  return new Response(stream, {
    headers: { "Content-Type": "text/event-stream" },
  });
};
返回
ReadableStream
类型的body实现流式响应(最大20 MB):
typescript
export default async (req: Request) => {
  const stream = new ReadableStream({ /* ... */ });
  return new Response(stream, {
    headers: { "Content-Type": "text/event-stream" },
  });
};

Context Object

Context对象

PropertyDescription
context.params
Path parameters from config
context.geo
{ city, country: {code, name}, latitude, longitude, subdivision, timezone, postalCode }
context.ip
Client IP address
context.cookies
.get()
,
.set()
,
.delete()
context.deploy
{ context, id, published }
context.site
{ id, name, url }
context.account.id
Team account ID
context.requestId
Unique request ID
context.waitUntil(promise)
Extend execution after response is sent
属性说明
context.params
来自配置的路径参数
context.geo
地理位置信息:
{ city, country: {code, name}, latitude, longitude, subdivision, timezone, postalCode }
context.ip
客户端IP地址
context.cookies
提供
.get()
.set()
.delete()
方法操作Cookie
context.deploy
部署信息:
{ context, id, published }
context.site
站点信息:
{ id, name, url }
context.account.id
团队账户ID
context.requestId
唯一请求ID
context.waitUntil(promise)
发送响应后延长函数执行时间

Environment Variables

环境变量

Use
Netlify.env
(not
process.env
) inside functions:
typescript
const apiKey = Netlify.env.get("API_KEY");
在函数内部使用
Netlify.env
获取环境变量(不要使用
process.env
):
typescript
const apiKey = Netlify.env.get("API_KEY");

Resource Limits

资源限制

ResourceLimit
Synchronous timeout60 seconds
Background timeout15 minutes
Scheduled timeout30 seconds
Memory1024 MB
Buffered payload6 MB
Streamed payload20 MB
资源限制
同步函数超时时间60秒
后台函数超时时间15分钟
定时函数超时时间30秒
内存1024 MB
缓冲负载6 MB
流式负载20 MB

Framework Considerations

框架适配注意事项

Frameworks with server-side capabilities (Astro, Next.js, Nuxt, SvelteKit, TanStack Start) typically generate their own serverless functions via adapters. You usually do not write raw Netlify Functions in these projects — the framework adapter handles server-side rendering and API routes. Write Netlify Functions directly when:
  • Using a client-side-only framework (Vite + React SPA, vanilla JS)
  • Adding background or scheduled tasks to any project
  • Building standalone API endpoints outside the framework's routing
See the netlify-frameworks skill for adapter setup.
具备服务端能力的框架(Astro、Next.js、Nuxt、SvelteKit、TanStack Start)通常会通过适配器自动生成对应的无服务器函数,这类项目中一般不需要手动编写原生Netlify Functions,框架适配器会处理服务端渲染和API路由。以下场景适合直接编写Netlify Functions:
  • 使用仅客户端的框架(Vite + React SPA、原生JS)
  • 为任意项目添加后台或定时任务
  • 构建脱离框架路由的独立API端点
请参考netlify-frameworks skill了解适配器配置方法。