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 内部运行时模块,应用代码不要使用。