INTEGRITY Dokumentace

Pages Plugins

Cloudflare udržuje řadu oficiálních Pages Plugins, které můžete použít ve svých projektech Pages:


Vytvoření Pages Plugin

Pages Plugin je distribuovatelný balíček Pages Functions, který zahrnuje vestavěné směrování a funkcionalitu. Vývojáři mohou Plugin zařadit do svého projektu Pages kdekoli se rozhodnou a předat mu konfigurační možnosti. Pluginům je k dispozici veškerá síla Functions, včetně middleware, parametrizovaných tras a statických aktiv.

Plugin Pages může například:

Pages Plugin je v podstatě knihovna, kterou vývojáři mohou použít k rozšíření svého existujícího projektu Pages o hlubokou integraci s Functions.

Použití funkce Pages Plugin

Vývojáři mohou své projekty rozšířit připojením pluginu Pages na trase své aplikace. Pluginy poskytují pokyny, kam by měly být obvykle připojeny (například administrační rozhraní může být připojeno na functions/admin/[[path]].ts, a logger chyb může být připojen na functions/_middleware.ts). Každý Plugin může navíc vyžadovat určitou konfiguraci (například pomocí API tokenu).


Příklad statického formuláře

V tomto příkladu vytvoříte Pages Plugin a poté ho zahrnete do projektu.

První plugin by měl:

1. Vytvořte nový Pages Plugin

Vytvořte package.json následujícím:

{
	"name": "@cloudflare/static-form-interceptor",
	"main": "dist/index.js",
	"types": "index.d.ts",
	"files": ["dist", "index.d.ts", "tsconfig.json"],
	"scripts": {
		"build": "npx wrangler pages functions build --plugin --outdir=dist",
		"prepare": "npm run build"
	}
}

V našem příkladu dist/index.js bude vstupním bodem vašeho Pluginu. Jde o vygenerovaný soubor, který sestaví Wrangler s npm run build příkaz. Přidejte dist/ adresář do svého .gitignore.

Dále vytvořte functions adresář a začněte psát kód svého Pluginu. functions složka připojí vývojářem k určité cestě, proto zvažte, jak chcete soubory strukturovat. Obecně platí:

Můžete použít libovolný počet různých souborů. Struktura Plugin je dnes naprosto stejná jako u Functions v projektu Pages, s tím rozdílem, že handlery obdrží novou vlastnost objektu parametrů, pluginArgs. Tato vlastnost je inicializační parametr, který vývojář předává při připojování Pluginu. Můžete ji využít k přijímání API tokenů, jmenných prostorů KV/Durable Object nebo čehokoli dalšího, co váš Plugin potřebuje ke svému fungování.

Vrátíme-li se k příkladu vašeho statického formuláře, pokud chcete zachytávat požadavky a přepsat chování HTML formuláře, musíte vytvořit functions/_middleware.ts. Vývojáři pak mohli váš Plugin připojit na jedinou route nebo na celý svůj projekt.

class FormHandler {
	element(element) {
		const name = element.getAttribute("data-static-form-name");
		element.setAttribute("method", "POST");
		element.removeAttribute("action");
		element.append(
			`<input type="hidden" name="static-form-name" value="${name}" />`,
			{ html: true },
		);
	}
}

export const onRequestGet = async (context) => {
	// We first get the original response from the project
	const response = await context.next();

	// Then, using HTMLRewriter, we transform `form` elements with a `data-static-form-name` attribute, to tell them to POST to the current page
	return new HTMLRewriter()
		.on("form[data-static-form-name]", new FormHandler())
		.transform(response);
};

export const onRequestPost = async (context) => {
	// Parse the form
	const formData = await context.request.formData();
	const name = formData.get("static-form-name");
	const entries = Object.fromEntries(
		[...formData.entries()].filter(([name]) => name !== "static-form-name"),
	);

	// Get the arguments given to the Plugin by the developer
	const { kv, respondWith } = context.pluginArgs;

	// Store form data in KV under key `form-name:YYYY-MM-DDTHH:MM:SSZ`
	const key = `${name}:${new Date().toISOString()}`;
	context.waitUntil(kv.put(name, JSON.stringify(entries)));

	// Respond with whatever the developer wants
	const response = await respondWith({ formData });
	return response;
};

2. Otypujte svůj Pages Plugin

Chcete-li vývojářům zajistit dobrý komfort práce, zvažte přidání typování TypeScript do svého pluginu. Vývojáři pak mohou využívat funkce IDE pro automatické doplňování a zároveň mají jistotu, že zahrnuli všechny očekávané parametry.

V index.d.ts, exportujte funkci, která přebírá váš pluginArgs a vrátí PagesFunction. U svého příkladu statického formuláře použijete dvě vlastnosti, kv, jmenný prostor KV a respondWith, funkce, která přijímá objekt s formData vlastnost (FormData) a vrátí Promise z Response:

export type PluginArgs = {
	kv: KVNamespace;
	respondWith: (args: { formData: FormData }) => Promise<Response>;
};

export default function (args: PluginArgs): PagesFunction;

3. Otestujte svůj Pages Plugin

Na skvělém testovacím prostředí pro autory Pages Plugins stále pracujeme. Prosíme o trpělivost, než se všechny části spojí dohromady. Mezitím si můžete vytvořit ukázkový projekt a svůj Plugin do něj pro účely testování zahrnout ručně.

4. Publikujte svůj Pages Plugin

Svůj Plugin můžete distribuovat, jak uznáte za vhodné. Mezi oblíbené možnosti patří publikování na npm, a pochlubte se jím v kanálech #what-i-built nebo #pages-discussions na našem Developer Discord, a zveřejnění jako open source na GitHub.

Zkontrolujte, že zahrnujete vygenerovaný dist/ adresáři budou vaše typové definice index.d.ts, stejně jako README.md s pokyny, jak mohou vývojáři váš Plugin používat.


5. Nainstalujte svůj Pages Plugin

Pokud chcete do své aplikace zahrnout Pages Plugin, musíte jej nejprve nainstalovat do svého projektu.

Pokud ještě nepoužíváte npm ve svém projektu spusťte npm init pro vytvoření package.json soubor. Soubor tohoto pluginu README.md obvykle obsahuje instalační příkaz (například npm install --save @cloudflare/static-form-interceptor).

6. Připojte svůj Pages Plugin

README.md Pluginu obvykle obsahuje pokyny, jak Plugin připojit (mount) ve vaší aplikaci. Budete muset:

  1. Vytvořte functions adresář, pokud ještě žádný nemáte.
  2. Rozhodněte se, kde má tento Plugin běžet, a vytvořte odpovídající soubor ve functions adresář.
  3. Importujte Plugin a exportujte onRequest metodu v tomto souboru a inicializuje Plugin s libovolnými argumenty, které vyžaduje.

V příkladu se statickým formulářem byl Plugin, který jste vytvořili, vytvořen jako middleware. To znamená, že může běžet buď na jediné route, nebo napříč celým projektem. Pokud byste měli na svém webu jediný kontaktní formulář na adrese /contact, můžete vytvořit functions/contact.ts soubor, který zachytí pouze danou trasu. Můžete také vytvořit functions/_middleware.ts soubor, který zachytí všechny ostatní trasy a jakékoli další formuláře, které v budoucnu vytvoříte. Jako vývojář si můžete zvolit, kde tento Plugin poběží.

Výchozí export Pluginu je funkce, která přijímá stejný parametr kontextu jako běžný handler Pages Functions.

import staticFormInterceptorPlugin from "@cloudflare/static-form-interceptor";

export const onRequest = (context) => {
	return staticFormInterceptorPlugin({
		kv: context.env.FORM_KV,
		respondWith: async ({ formData }) => {
			// Could call email/notification service here
			const name = formData.get("name");
			return new Response(`Thank you for your submission, ${name}!`);
		},
	})(context);
};

7. Otestujte svůj Pages Plugin

Můžete použít wrangler pages dev k otestování projektu Pages, včetně všech nainstalovaných Pluginů. Nezapomeňte zahrnout i všechny vazby KV a proměnné prostředí, které Plugin očekává.

Jakmile je váš Plugin připojený na /contact cestu, odpovídající soubor HTML by mohl vypadat takto:

<!DOCTYPE html>
<html>
	<body>
		<h1>Contact us</h1>
		<!-- Include the `data-static-form-name` attribute to name the submission -->
		<form data-static-form-name="contact">
			<label>
				<span>Name</span>
				<input type="text" autocomplete="name" name="name" />
			</label>
			<label>
				<span>Message</span>
				<textarea name="message"></textarea>
			</label>
		</form>
	</body>
</html>

Váš plugin by měl automaticky rozpoznat data-static-form-name="contact" atribut, nastavte method="POST", vložte do <input type="hidden" name="static-form-name" value="contact" /> element a zachytit POST odeslání.

8. Nasaďte svůj projekt Pages

Zkontrolujte, že byl nový Plugin přidán do vašeho package.json a že vše funguje lokálně podle očekávání. Poté můžete git commit a git push a spusťte nasazení Cloudflare Pages.

Pokud narazíte na problém s některým Pluginem, nahlaste issue v jeho bug trackeru.

Pokud narazíte na jakékoli problémy s Pluginy obecně, oceníme vaši zpětnou vazbu v kanálu #pages-discussions na Discord! Těšíme se, co s Pluginy vytvoříte, a uvítáme jakoukoli zpětnou vazbu k tvorbě nebo vývojářskému zážitku. Pokud potřebujete cokoli, co by Pluginy ještě více zdokonalilo, dejte nám vědět na Discord kanálu.


Zařaďte svůj plugin do řetězce

Nakonec, stejně jako u Pages Functions obecně, můžete zřetězit Plugins a kombinovat tak různé funkce. Middleware definovaný výše v souborovém systému se spustí dříve než ostatní obslužné rutiny a jednotlivé soubory mohou zřetězit Functions v poli takto:

import sentryPlugin from "@cloudflare/pages-plugin-sentry";
import cloudflareAccessPlugin from "@cloudflare/pages-plugin-cloudflare-access";
import adminDashboardPlugin from "@cloudflare/a-fictional-admin-plugin";

export const onRequest = [
	// Initialize a Sentry Plugin to capture any errors
	sentryPlugin({ dsn: "https://sentry.io/welcome/xyz" }),

	// Initialize a Cloudflare Access Plugin to ensure only administrators can access this protected route
	cloudflareAccessPlugin({
		domain: "https://test.cloudflareaccess.com",
		aud: "4714c1358e65fe4b408ad6d432a5f878f08194bdb4752441fd56faefa9b2b6f2",
	}),

	// Populate the Sentry plugin with additional information about the current user
	(context) => {
		const email =
			context.data.cloudflareAccessJWT.payload?.email || "service user";

		context.data.sentry.setUser({ email });

		return next();
	},

	// Finally, serve the admin dashboard plugin, knowing that errors will be captured and that every incoming request has been authenticated
	adminDashboardPlugin(),
];