@soloworks/smking-next 0.22.0 → 0.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/package.json +1 -1
- package/src/components/smking-cms.tsx +7 -2
- package/src/lib/sitemap.ts +8 -2
- package/src/lib/version.ts +1 -1
- package/src/lib/webhook-route.ts +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @soloworks/smking-next
|
|
2
2
|
|
|
3
|
+
## 0.22.2 — 2026-07-26
|
|
4
|
+
|
|
5
|
+
- `<SmkingCms>` now calls Next.js `notFound()` when Page Zero explicitly
|
|
6
|
+
reports an unpublished or missing slug, producing a real 404 instead of an
|
|
7
|
+
empty 200 page.
|
|
8
|
+
- Network failures, pending content, and missing configuration still fail open.
|
|
9
|
+
|
|
10
|
+
## 0.22.1 — 2026-07-26
|
|
11
|
+
|
|
12
|
+
- Sitemap fetches now carry a shared cache tag.
|
|
13
|
+
- Signed AEO and CMS publish webhooks immediately invalidate the sitemap tag,
|
|
14
|
+
so newly published Blog pages do not wait for the one-day fallback TTL.
|
|
15
|
+
|
|
3
16
|
## 0.22.0 — 2026-07-25
|
|
4
17
|
|
|
5
18
|
- AEO requests now skip the configured `SMKING_CMS_PATH`, preventing duplicate
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soloworks/smking-next",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.2",
|
|
4
4
|
"description": "AI-native SEO (AEO) for Next.js — auto-inject JSON-LD, FAQ, AI summary, and SEO metadata so AI crawlers (ChatGPT, Perplexity, Google AI) can cite your pages.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/sillyleo/smking/tree/main/packages/smking-next",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cookies, draftMode } from "next/headers";
|
|
2
|
+
import { notFound } from "next/navigation";
|
|
2
3
|
|
|
3
4
|
import { getCmsPage } from "../lib/cms-client";
|
|
4
5
|
import { safeJson } from "../lib/safe-json";
|
|
@@ -32,8 +33,9 @@ import type { CmsParams } from "../types";
|
|
|
32
33
|
* from this package via `lib/smking-cms-styles`) alongside, which
|
|
33
34
|
* targets `.slate-*` hooks in plain CSS.
|
|
34
35
|
*
|
|
35
|
-
*
|
|
36
|
-
* unreachable
|
|
36
|
+
* Calls Next.js `notFound()` when the API explicitly reports `not_found`.
|
|
37
|
+
* Pending, unreachable, and mis-configured responses still return null so
|
|
38
|
+
* transient infrastructure failures remain fail-open.
|
|
37
39
|
*
|
|
38
40
|
* Emits `<title>` / `<meta>` / `og:*` / canonical inline; React 19
|
|
39
41
|
* hoists them into `<head>` automatically.
|
|
@@ -63,6 +65,9 @@ export async function SmkingCms(props: CmsParams) {
|
|
|
63
65
|
const data = await getCmsPage(
|
|
64
66
|
previewToken ? { ...props, previewToken } : props,
|
|
65
67
|
);
|
|
68
|
+
if (data?.status === "not_found") {
|
|
69
|
+
notFound();
|
|
70
|
+
}
|
|
66
71
|
if (
|
|
67
72
|
!data ||
|
|
68
73
|
(data.status !== "ready" && data.status !== "preview") ||
|
package/src/lib/sitemap.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { MetadataRoute } from "next";
|
|
2
2
|
|
|
3
|
+
export const SMKING_SITEMAP_CACHE_TAG = "smking:sitemap";
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Drop-in `app/sitemap.ts` default export. Fetches the canonical sitemap
|
|
5
7
|
* served by Page Zero at `/api/v1/public/sitemap.xml?key=...`, parses
|
|
@@ -36,8 +38,12 @@ export default async function smkingSitemap(): Promise<MetadataRoute.Sitemap> {
|
|
|
36
38
|
`${baseUrl}/api/v1/public/sitemap.xml?key=${encodeURIComponent(apiKey)}`,
|
|
37
39
|
{
|
|
38
40
|
// Daily revalidation — sitemap doesn't change second-to-second.
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
+
// The signed publish webhook invalidates this tag immediately when
|
|
42
|
+
// AEO or CMS content changes; the TTL remains the fail-safe.
|
|
43
|
+
next: {
|
|
44
|
+
revalidate: 86_400,
|
|
45
|
+
tags: [SMKING_SITEMAP_CACHE_TAG],
|
|
46
|
+
},
|
|
41
47
|
signal: AbortSignal.timeout(10_000),
|
|
42
48
|
},
|
|
43
49
|
);
|
package/src/lib/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "0.22.
|
|
1
|
+
export const SDK_VERSION = "0.22.2";
|
package/src/lib/webhook-route.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { revalidateTag } from "next/cache";
|
|
2
2
|
import { Buffer } from "node:buffer";
|
|
3
3
|
import crypto from "node:crypto";
|
|
4
|
+
import { SMKING_SITEMAP_CACHE_TAG } from "./sitemap";
|
|
4
5
|
|
|
5
6
|
interface WebhookPayload {
|
|
6
7
|
kind?: string;
|
|
@@ -153,6 +154,23 @@ export async function POST(request: Request): Promise<Response> {
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
|
|
157
|
+
// The canonical sitemap fetch has a daily TTL. A publish must evict it
|
|
158
|
+
// immediately or newly published CMS pages can stay absent for 24 hours.
|
|
159
|
+
// Limit this shared tag to content kinds that actually affect the sitemap;
|
|
160
|
+
// unknown future payloads keep their forward-compatible no-op behavior.
|
|
161
|
+
if (kind === "aeo" || kind === "cms_page") {
|
|
162
|
+
try {
|
|
163
|
+
revalidateTag(SMKING_SITEMAP_CACHE_TAG, "default");
|
|
164
|
+
revalidated++;
|
|
165
|
+
} catch (err) {
|
|
166
|
+
errors++;
|
|
167
|
+
console.warn(
|
|
168
|
+
"[@soloworks/smking-next/webhook] sitemap revalidateTag failed:",
|
|
169
|
+
err,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
156
174
|
return Response.json({ ok: true, kind, revalidated, errors });
|
|
157
175
|
}
|
|
158
176
|
|