@blawness/admin-kit
v0.7.3
Published
Reusable CMS core for Next.js 16 admin panels — auth, media, users, editor, shell
Maintainers
Readme
@blawness/admin-kit
Reusable CMS core (auth, media, users, editor, admin shell, shared components) extracted from the LIPAN RI site. Consumed as a private Git dependency.
Consumer setup
pnpm add github:Blawness/admin-kit#vX.Y.Z- Add to
next.config:transpilePackages: ["@blawness/admin-kit"] - Ensure Tailwind scans the package and defines the
navy/brand/goldtokens.
Public cached reads (@blawness/admin-kit/public)
Render published articles on your public site with caching wired to the admin mutations out of the box:
import {
getPublishedArticles,
getPublishedArticleBySlug,
getPublishedArticleSlugs,
} from "@blawness/admin-kit/public";
// app/berita/page.tsx
const posts = await getPublishedArticles({ limit: 12 });
// app/berita/[slug]/page.tsx
export async function generateStaticParams() {
return (await getPublishedArticleSlugs()).map((slug) => ({ slug }));
}
const post = await getPublishedArticleBySlug(slug); // null if not found/unpublishedThese helpers use the Next.js 16 use cache directive, so the consumer must
enable it:
// next.config.ts
const nextConfig = { cacheComponents: true };Every read is tagged ARTICLES_TAG ("articles"); the admin actions call
revalidateTag("articles") on every create/update/publish/reject/delete, so the
public pages refresh automatically. This entry point is isolated — importing the
rest of the package does not require cacheComponents.
SEO & feeds
Articles carry excerpt, metaTitle, metaDescription, and ogImage (edit
them in the article form's SEO section). Generate a sitemap and RSS feed from the
same cached/tagged layer:
// app/sitemap.ts
import { getSitemapEntries } from "@blawness/admin-kit/public";
export default async function sitemap() {
return getSitemapEntries({ siteUrl: "https://example.com", articleBasePath: "/berita" });
}
// app/rss.xml/route.ts
import { generateRssXml } from "@blawness/admin-kit/public";
export async function GET() {
const xml = await generateRssXml({
siteUrl: "https://example.com",
title: "Berita Example",
description: "Artikel terbaru",
});
return new Response(xml, { headers: { "Content-Type": "application/rss+xml" } });
}Apply the migration in drizzle/0001_*.sql (pnpm db:migrate) before using the
new fields.
Admin list pagination & search
The articles screen now supports ?q= (title/slug search) and ?page=
pagination; the media gallery supports ?page=. The data helpers
(listArticles, countArticles, listMedia, countMedia) accept
limit/offset so large datasets no longer load every row.
Phase 1 result
- Directive preservation: CONFIRMED (
"use client"intact in dist after tsc build). - Consumed by a Next.js 16.2.7 throwaway app via
transpilePackages+ Git-tag dependency: build PASSED, page rendered (HTTP 200). - Gotchas: pnpm v10 blocks the git dep's
preparescript by default (ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED) — the consumer must add@blawness/admin-kittopnpm.onlyBuiltDependenciesin package.json (or pnpm-workspace.yaml) so tsc runs anddist/builds. Thenoopserver action can be typed() => Promise<void>even thoughConfirmDelete'sactionprop is(formData: FormData) => Promise<void>— Next/TS accepts the narrower no-arg signature.
