@morphika/andami 0.8.3 → 0.8.5

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/app/layout.tsx CHANGED
@@ -2,6 +2,9 @@ import type { Metadata } from "next";
2
2
  import { VisualEditing } from "next-sanity/visual-editing";
3
3
  import { draftMode } from "next/headers";
4
4
  import { registerConfig, getSiteConfig } from "../lib/config";
5
+ import { getCachedSiteSettings } from "../lib/seo/site-settings";
6
+ import { assetUrl } from "../lib/assets";
7
+ import { buildFaviconMetadata } from "../lib/seo/favicon";
5
8
  import siteConfig from "../site.config";
6
9
  import "./globals.css";
7
10
 
@@ -12,26 +15,40 @@ registerConfig(siteConfig);
12
15
 
13
16
  const cfg = getSiteConfig();
14
17
 
15
- export const metadata: Metadata = {
16
- title: {
17
- default: cfg.defaults.metaTitle,
18
- template: `%s ${cfg.name}`,
19
- },
20
- description: cfg.defaults.metaDescription,
21
- metadataBase: new URL(cfg.domain),
22
- openGraph: {
23
- title: cfg.defaults.metaTitle,
24
- description: cfg.defaults.metaDescription,
25
- siteName: cfg.name,
26
- type: "website",
27
- url: cfg.domain,
28
- },
29
- twitter: {
30
- card: "summary_large_image",
31
- title: cfg.defaults.metaTitle,
18
+ // Use generateMetadata (dynamic) instead of `export const metadata` (static)
19
+ // so we can read `siteSettings.favicon_path` from Sanity per render. The
20
+ // underlying `getCachedSiteSettings()` is React-cache-dedup'd across the same
21
+ // render pass, so SiteSeoHead (which also reads settings) shares the fetch.
22
+ // With ISR enabled on pages, this effectively means one Sanity read per page
23
+ // per revalidation window — negligible cost.
24
+ export async function generateMetadata(): Promise<Metadata> {
25
+ const settings = await getCachedSiteSettings();
26
+ const faviconUrl = settings?.favicon_path
27
+ ? assetUrl(settings.favicon_path)
28
+ : undefined;
29
+
30
+ return {
31
+ title: {
32
+ default: cfg.defaults.metaTitle,
33
+ template: `%s — ${cfg.name}`,
34
+ },
32
35
  description: cfg.defaults.metaDescription,
33
- },
34
- };
36
+ metadataBase: new URL(cfg.domain),
37
+ icons: buildFaviconMetadata(faviconUrl),
38
+ openGraph: {
39
+ title: cfg.defaults.metaTitle,
40
+ description: cfg.defaults.metaDescription,
41
+ siteName: cfg.name,
42
+ type: "website",
43
+ url: cfg.domain,
44
+ },
45
+ twitter: {
46
+ card: "summary_large_image",
47
+ title: cfg.defaults.metaTitle,
48
+ description: cfg.defaults.metaDescription,
49
+ },
50
+ };
51
+ }
35
52
 
36
53
  export default async function RootLayout({
37
54
  children,
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Favicon — builder for the Next.js Metadata.icons field.
3
+ *
4
+ * The favicon URL should be pre-resolved to an absolute or root-relative
5
+ * URL by the caller (e.g. via assetUrl()) — this helper just shapes the
6
+ * Metadata.icons value and handles the empty case.
7
+ *
8
+ * Returns undefined when no URL is supplied so callers can spread the
9
+ * result into a Metadata object without leaving an empty `icons` field
10
+ * (Next.js would otherwise emit a default favicon hint).
11
+ */
12
+
13
+ import type { Metadata } from "next";
14
+
15
+ export function buildFaviconMetadata(
16
+ faviconUrl: string | null | undefined
17
+ ): Metadata["icons"] | undefined {
18
+ if (!faviconUrl) return undefined;
19
+ return { icon: faviconUrl };
20
+ }
package/lib/version.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * Exposed as a plain constant so it can be imported without reading
7
7
  * package.json at runtime.
8
8
  */
9
- export const ANDAMI_VERSION = "0.8.3";
9
+ export const ANDAMI_VERSION = "0.8.5";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morphika/andami",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "description": "Visual Page Builder — core library. A reusable website builder with visual editing, CMS integration, and asset management.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -82,6 +82,7 @@
82
82
  "./lib/editor": "./lib/editor/index.ts",
83
83
  "./lib/editor/*": "./lib/editor/*.ts",
84
84
  "./lib/animation/*": "./lib/animation/*.ts",
85
+ "./lib/seo/*": "./lib/seo/*.ts",
85
86
  "./lib/shader/glsl": "./lib/shader/glsl/index.ts",
86
87
  "./lib/backup/manifest": "./lib/backup/manifest.ts",
87
88
  "./lib/backup/export": "./lib/backup/export.ts",