@tangle-network/brand 1.31.8 → 1.31.9

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.31.9
4
+
5
+ ### Patch Changes
6
+
7
+ - d5ff1b5: Compose route and document metadata through one shared owner, keeping canonical URLs on the product origin and rejecting partial social overrides.
8
+
3
9
  ## 1.31.8
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -28,6 +28,14 @@ current supported contract and a real preview check. This helper does not fetch
28
28
  media, prove its MIME/codec/duration/range/cache behavior, or approve publication.
29
29
  Verify those against the served files. Canonical URLs omit query and fragment.
30
30
 
31
+ For routers that replace parent metadata, `pageMetadata(page, { pathname,
32
+ overrides })` returns the document title, description, social tags and canonical
33
+ link as descriptors. Route title/description overrides update both preview
34
+ formats; blank overrides retain the page defaults. Other descriptors, such as
35
+ robots and JSON-LD, pass through. The pathname stays on the page's origin.
36
+ Set verified media on `page`; partial
37
+ Open Graph or Twitter overrides are rejected to prevent contradictory cards.
38
+
31
39
  ### Tailwind v4
32
40
 
33
41
  ```css
package/dist/social.d.ts CHANGED
@@ -35,4 +35,16 @@ export type SocialMetaTag = {
35
35
  export declare function socialMetadata(page: SocialPage): {
36
36
  canonicalUrl: string;
37
37
  tags: SocialMetaTag[];
38
- };
38
+ };
39
+ export type PageMetadataTag = SocialMetaTag | {
40
+ title: string;
41
+ } | {
42
+ tagName: "link";
43
+ rel: "canonical";
44
+ href: string;
45
+ };
46
+ /** Compose document metadata after a route replaces its parent's descriptors. */
47
+ export declare function pageMetadata<Descriptor extends object = never>(page: SocialPage, { pathname, overrides }?: {
48
+ pathname?: string;
49
+ overrides?: readonly Descriptor[];
50
+ }): Array<PageMetadataTag | Descriptor>;
package/dist/social.js CHANGED
@@ -105,4 +105,40 @@ function socialMetadata(page) {
105
105
  ]
106
106
  };
107
107
  }
108
- export { socialMetadata };
108
+ /** Compose document metadata after a route replaces its parent's descriptors. */
109
+ function pageMetadata(page, { pathname, overrides = [] } = {}) {
110
+ let { title, description } = page;
111
+ const extra = [];
112
+ for (const tag of overrides) {
113
+ const data = tag;
114
+ if ([data.property, data.name].some((key) => typeof key === "string" && /^(og|twitter):/.test(key))) throw new Error("Pass verified social fields on the page, not partial route overrides");
115
+ if ("title" in data) {
116
+ if (typeof data.title === "string" && data.title.trim()) title = data.title;
117
+ } else if (data.name === "description") {
118
+ if (typeof data.content === "string" && data.content.trim()) description = data.content;
119
+ } else if (!(data.tagName === "link" && data.rel === "canonical")) extra.push(tag);
120
+ }
121
+ const url = httpsUrl(page.url);
122
+ if (pathname !== void 0) url.pathname = pathname;
123
+ const social = socialMetadata({
124
+ ...page,
125
+ title,
126
+ description,
127
+ url: url.href
128
+ });
129
+ return [
130
+ { title },
131
+ {
132
+ name: "description",
133
+ content: description
134
+ },
135
+ ...social.tags,
136
+ {
137
+ tagName: "link",
138
+ rel: "canonical",
139
+ href: social.canonicalUrl
140
+ },
141
+ ...extra
142
+ ];
143
+ }
144
+ export { pageMetadata, socialMetadata };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/brand",
3
- "version": "1.31.8",
3
+ "version": "1.31.9",
4
4
  "description": "Tangle brand system — design tokens, logo, Tailwind v4 theme. Single source of truth for every Tangle app.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/social.ts CHANGED
@@ -91,3 +91,37 @@ export function socialMetadata(page: SocialPage): {
91
91
  ],
92
92
  };
93
93
  }
94
+
95
+ export type PageMetadataTag = SocialMetaTag
96
+ | { title: string }
97
+ | { tagName: "link"; rel: "canonical"; href: string };
98
+
99
+ /** Compose document metadata after a route replaces its parent's descriptors. */
100
+ export function pageMetadata<Descriptor extends object = never>(
101
+ page: SocialPage,
102
+ { pathname, overrides = [] }: { pathname?: string; overrides?: readonly Descriptor[] } = {},
103
+ ): Array<PageMetadataTag | Descriptor> {
104
+ let { title, description } = page;
105
+ const extra: Descriptor[] = [];
106
+ for (const tag of overrides) {
107
+ const data = tag as Record<string, unknown>;
108
+ if ([data.property, data.name].some(key => typeof key === "string" && /^(og|twitter):/.test(key))) {
109
+ throw new Error("Pass verified social fields on the page, not partial route overrides");
110
+ }
111
+ if ("title" in data) {
112
+ if (typeof data.title === "string" && data.title.trim()) title = data.title;
113
+ } else if (data.name === "description") {
114
+ if (typeof data.content === "string" && data.content.trim()) description = data.content;
115
+ } else if (!(data.tagName === "link" && data.rel === "canonical")) extra.push(tag);
116
+ }
117
+ const url = httpsUrl(page.url);
118
+ if (pathname !== undefined) url.pathname = pathname;
119
+ const social = socialMetadata({ ...page, title, description, url: url.href });
120
+ return [
121
+ { title },
122
+ { name: "description", content: description },
123
+ ...social.tags,
124
+ { tagName: "link", rel: "canonical", href: social.canonicalUrl },
125
+ ...extra,
126
+ ];
127
+ }