@itmaster/sdk
One dependency wires a Next.js site to the engine: pull finished articles, serve robots.txt / sitemap.xml / rss.xml / llms.txt, source the engine-managed <head>, host the IndexNow key, and receive publish webhooks — mostly one line per feature.
Quickstart — the init CLI
Scaffold a site by selecting features. It writes only new files (client + the routes you pick + middleware), adds env keys, and prints the two snippets it won't overwrite.
npm i @itmaster/sdk
npx @itmaster/sdk init # interactive (y/n per feature)
# or non-interactive:
npx @itmaster/sdk init \
--site <PUBLISH_SITE> --engine https://itmaster.uk \
--features robots,sitemap,rss,llms,indexnow,webhook --yesSetup
Register the site engine-side (issues a pull key), set env, create the shared client. No pull key just means every call returns null and the site still renders.
# .env.local
ITMASTER_API_URL=https://itmaster.uk
PUBLISH_SITE=<your TargetSite id>
PUBLISH_PULL_KEY=<per-site key>// lib/itmaster.ts
import { createClient } from "@itmaster/sdk";
export const itmaster = createClient({
baseUrl: process.env.ITMASTER_API_URL!,
site: process.env.PUBLISH_SITE!,
pullKey: process.env.PUBLISH_PULL_KEY ?? "",
});What you get
The one-liners
Derived feeds are a single re-export:
// app/robots.txt/route.ts (same shape for sitemap.xml / rss.xml / llms.txt)
import { createRobotsRoute } from "@itmaster/sdk/next";
import { itmaster } from "@/lib/itmaster";
export const GET = createRobotsRoute(itmaster);IndexNow derives the exact key the engine submits — no secret, no round-trip:
// app/api/indexnow-key/route.ts
import { createIndexNowKeyRoute } from "@itmaster/sdk/next";
export const GET = createIndexNowKeyRoute(process.env.PUBLISH_SITE ?? "your-site");
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
export function middleware(req: NextRequest) {
if (/^\/[a-f0-9]{32}\.txt$/.test(req.nextUrl.pathname))
return NextResponse.rewrite(new URL("/api/indexnow-key", req.url));
return NextResponse.next();
}
export const config = { matcher: ["/((?!_next/|favicon.ico).*)"] };Engine-managed head — verification/OG/favicon via the Metadata API (the only path that reaches <head> in the App Router):
// app/layout.tsx
import { applyMeta } from "@itmaster/sdk/next";
import { itmaster } from "@/lib/itmaster";
const base = { /* your defaults */ };
export async function generateMetadata() {
const config = await itmaster.config().catch(() => null);
return config ? applyMeta(base, config) : base;
}Then connect Google — zero-click
Once the head + IndexNow routes are live, one engine call verifies the site in Search Console, submits the sitemap, and turns on indexing (Google Indexing API + IndexNow).
curl -X POST "https://itmaster.uk/v1/publish/sites/<site>/connect/google/auto" \
-H "Authorization: Bearer <INTERNAL_TOKEN>"Full reference, provider (write-back) mode, and the incremental mirror feed are in the README.