API
本页的内容都从 @mantou/gemkit 导入,另有说明的除外。除了 HttpError、formatTitle 和类型,它们都会自动导入。
路由
page
page(options?: string | PageOptions<P, D>): ClassDecorator标记页面模块的默认导出。字符串是页面标题,等同于 { title: options }。
@page<{ slug: string }, Post>({ load: ({ params }) => getPost(params.slug) })
export default class PostPage extends GemElement {
@property params!: { slug: string };
@property data?: Post;
}layout
layout(options?: LayoutOptions<P, D>): ClassDecorator标记 _layout.ts 的默认导出。布局对它下面的页面生效,在页面之间导航时保留。
PageOptions
| 选项 | 类型 | 说明 |
|---|---|---|
title |
string | (ctx: RouteContext<P, D>) => string | Promise<string> |
页面标题。 |
load |
(ctx: LoadContext<P>) => D | Promise<D> |
渲染前的同构数据加载。 |
meta |
Meta | (ctx: RouteContext<P, D>) => Meta | Promise<Meta> |
页面的 <meta>。 |
paths |
(ctx: { lang: string }) => P[] | Promise<P[]> |
预渲染动态路由使用的参数列表。 |
LayoutOptions 包含 load 和 meta。
RouteContext
interface RouteContext<P extends Params = Params, D = unknown> {
params: P;
data: D;
}params 是匹配到的路由参数。data 是 load 的结果;在 load 自身中,它是同名服务端模块 load 的结果。
Meta
type Meta = Record<string, string | undefined>;包含 : 的 key 输出为 <meta property>,其他的输出为 <meta name>。值为 undefined 时不输出。
服务端模块
同名的 <页面或布局>.server.ts 导出下面的内容,它们只在服务端执行。
load
export function load(ctx: ServerLoadContext<P>): unknown | Promise<unknown>;返回可以序列化成 JSON 的数据。它作为 data 传给页面或者布局的 load,没有 load 选项时直接使用。
可以调用 redirect、error 或者 notFound。
paths
export function paths(ctx: { lang: string }): Params[] | Promise<Params[]>;预渲染动态路由使用的参数列表。每种语言调用一次,优先于页面的 paths 选项。只对页面有效。
prerender
export const prerender = false;关闭这个路由的预渲染。在布局中设置时对它下面的所有页面生效。
actions
export const actions: Record<
string,
(ctx: ServerLoadContext) => unknown | Promise<unknown>
>;处理 POST <页面路径>?/<name>。表单的 action="?/login" 调用 actions.login,
同一个表单中带 formaction="?/logout" 的提交按钮调用 actions.logout。
返回可以序列化成 JSON 的值给 submitAction,或者使用 redirect、error、notFound。
请求
ServerLoadContext
interface ServerLoadContext<P extends Params = Params> extends RequestEvent {
params: P;
}RequestEvent
| 字段 | 类型 | 说明 |
|---|---|---|
url |
URL |
页面的 URL,包含语言前缀。 |
path |
string |
不包含语言前缀的页面路径,和路由匹配的路径一致。 |
request |
Request |
当前请求,预渲染时不可用。 |
cookies |
Cookies |
请求的 cookie,预渲染时不可用。 |
locals |
Locals |
同一个请求中服务端代码共享的数据。 |
getRequestEvent
getRequestEvent(): RequestEvent;返回当前服务端请求的事件。在请求之外调用(例如模块求值时、响应结束之后)会抛出错误。 它属于单个请求,不能保存到模块级变量中。
redirect
redirect(status: 301 | 302 | 303 | 307 | 308, location: string): never;抛出跳转。location 包含语言前缀。可以在 handle、load、actions 和 API 路由中使用。
error
error(status: number, message?: string): never;抛出错误,使用给定的状态码渲染错误页面。
notFound
notFound(): never;等同于 error(404, 'Not Found')。
HttpError
class HttpError extends Error {
status: number;
message: string;
}error() 抛出的错误,也是 $gemkit/api 在响应不成功时抛出的错误。
submitAction
submitAction(form: HTMLFormElement, submitter?: HTMLElement | null): Promise<unknown>;不刷新页面提交表单。成功时重新加载当前页面的数据,返回 action 的结果。跳转时客户端导航,
出错时渲染错误页面。请求期间表单有 aria-busy 属性。请求本身失败时抛出错误。
Cookies
interface Cookies {
get(name: string): string | undefined;
set(name: string, value: string, options?: CookieOptions): void;
delete(name: string, options?: Pick<CookieOptions, 'path' | 'domain'>): void;
}set 和 delete 会在响应中添加 Set-Cookie。同一个请求中,之后 get 可以读取新值。
CookieOptions
| 选项 | 类型 | 默认值 |
|---|---|---|
path |
string |
'/' |
domain |
string |
|
maxAge |
number,单位秒 |
|
expires |
Date |
|
httpOnly |
boolean |
true |
secure |
boolean |
HTTPS 时为 true |
sameSite |
'Strict' | 'Lax' | 'None' |
'Lax' |
Locals
interface Locals {}由应用扩展的空接口。在 handle 中写入,在 load、actions、API 路由和服务端元素中读取。
declare module '@mantou/gemkit' {
interface Locals {
user?: User;
}
}服务端元素
server
把类标记为纯服务端元素,或者让方法、字段在服务端渲染时执行。
@server()
class ServerOnly extends GemElement {}标记在成员上时,它在服务端渲染时执行,状态会输出到页面。结果必须可以序列化成 JSON。
lazy
lazy(options?: { on?: 'interaction' | 'load' | 'visible' }): ClassDecorator保留服务端的 HTML,直到客户端加载代码并水合。on 默认是 'interaction'。
client
client(): ClassDecorator只在客户端渲染。服务端输出标签,客户端正常渲染,不水合。服务端构建时模块会被替换成空模块。
工具
formatTitle
formatTitle(title: string | undefined, { title, titleTemplate }: TitleOptions): string;使用网站标题和标题模板格式化,和 Gemkit 内部的规则一致。
TitleOptions
interface TitleOptions {
title?: string;
titleTemplate?: string;
}生成的模块
$gemkit/i18n 的 i18n 和 $gemkit/api 的 apis 会自动导入。
$gemkit/i18n
| 导出 | 类型 |
|---|---|
i18n |
I18n<typeof defaultMessages> |
languages |
string[] |
defaultLanguage |
string |
prefixDefaultLanguage |
boolean |
localizePath |
(lang: string, path?: string) => string |
没有 locales 目录时,i18n 是 undefined,languages 为空,defaultLanguage 是 ''。
见
$gemkit/api
apis 根据 API 路由生成。静态路径段是属性,动态段是函数调用,最后是 HTTP 方法。
参数和结果从处理函数推导。JSON 响应会解析,其他响应返回 Response。响应不成功时 reject HttpError。
const likes = await apis.api.likes(slug).GET({ page: 1 });GET 和 DELETE 把输入作为查询参数,其他方法发送 JSON。
包的入口
| 导入 | 内容 |
|---|---|
@mantou/gemkit |
本页的 API。 |
@mantou/gemkit/plugin |
pluginGemkit、GemkitOptions 和 GemkitConfig。 |
@mantou/gemkit/server |
自定义集成使用的 createRenderer。 |
@mantou/gemkit/init |
gemkit init 使用的项目初始化器。 |
@mantou/gemkit/internal |
内部运行时模块,应用代码不要使用。 |
