@gudhub/ssg-web-components-library 1.0.111 → 1.0.112
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/package.json +1 -1
- package/src/components/meta/meta-tag.js +152 -87
package/package.json
CHANGED
|
@@ -10,6 +10,8 @@ class MetaTag extends GHComponent {
|
|
|
10
10
|
*/
|
|
11
11
|
constructor() {
|
|
12
12
|
super();
|
|
13
|
+
|
|
14
|
+
this.config = null;
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
async onServerRender() {
|
|
@@ -24,9 +26,15 @@ class MetaTag extends GHComponent {
|
|
|
24
26
|
const url = new URL(window.location.href);
|
|
25
27
|
const path = url.searchParams.get('path');
|
|
26
28
|
|
|
29
|
+
this.config = window.getConfig?.();
|
|
30
|
+
if (!this.config) {
|
|
31
|
+
console.warn('Config not available');
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
27
35
|
if (!appId && !itemId && path === ('/blog/')) { //blog/authors/
|
|
28
|
-
appId =
|
|
29
|
-
itemId =
|
|
36
|
+
appId = this.config.chapters.pages.app_id;
|
|
37
|
+
itemId = this.config.chapters.pages.blog_main_page_item_id;
|
|
30
38
|
|
|
31
39
|
this.addTag(appId, itemId, false, chapter);
|
|
32
40
|
} else {
|
|
@@ -34,12 +42,14 @@ class MetaTag extends GHComponent {
|
|
|
34
42
|
const author = url.searchParams.get('author');
|
|
35
43
|
const category = url.searchParams.get('category');
|
|
36
44
|
const article = url.searchParams.get('article');
|
|
45
|
+
|
|
37
46
|
if (appId && itemId) {
|
|
38
47
|
this.addTag(appId, itemId, false, chapter);
|
|
39
48
|
} else {
|
|
40
49
|
if (chapter == 'blog' && !itemId) {
|
|
41
50
|
const url = new URL(window.location.href);
|
|
42
51
|
const path = url.searchParams.get('path');
|
|
52
|
+
|
|
43
53
|
if (path.includes('/page/')) {
|
|
44
54
|
let slug = `/blog/${category}/`;
|
|
45
55
|
await this.addTag(appId, false, slug, chapter);
|
|
@@ -69,19 +79,20 @@ class MetaTag extends GHComponent {
|
|
|
69
79
|
}
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
|
-
|
|
73
82
|
}
|
|
83
|
+
|
|
74
84
|
async addTag (appId, itemId, slug, chapter) {
|
|
75
85
|
const app = await gudhub.getApp(appId);
|
|
76
86
|
const items = app.items_list;
|
|
87
|
+
|
|
77
88
|
let item;
|
|
78
89
|
let fieldId;
|
|
79
90
|
let value;
|
|
91
|
+
|
|
80
92
|
if (!slug) {
|
|
81
93
|
item = items.find(findedItem => findedItem.item_id == itemId);
|
|
82
94
|
} else {
|
|
83
95
|
for (let findedItem in items) {
|
|
84
|
-
|
|
85
96
|
let iterationItem = items[findedItem].fields.find(field => field.field_value == slug)
|
|
86
97
|
if (iterationItem) {
|
|
87
98
|
item = items[findedItem];
|
|
@@ -89,158 +100,212 @@ class MetaTag extends GHComponent {
|
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
102
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
103
|
+
const chapterConfig = this.config?.chapters?.[chapter];
|
|
104
|
+
if (!chapterConfig) {
|
|
105
|
+
console.warn('Invalid chapter:', chapter);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const chapterItemId = item?.item_id;
|
|
110
|
+
const fields = item?.fields ?? [];
|
|
111
|
+
const generalInfo = this.config.componentsConfigs?.generalInfo?.[0];
|
|
112
|
+
|
|
113
|
+
const {
|
|
114
|
+
title_field_id: titleId,
|
|
115
|
+
description_field_id: descriptionId,
|
|
116
|
+
slug_field_id: slugId,
|
|
117
|
+
image_field_id: imageId,
|
|
118
|
+
meta_image_field_id: metaImageIdRaw,
|
|
119
|
+
app_id: chapterAppId
|
|
120
|
+
} = chapterConfig;
|
|
121
|
+
|
|
122
|
+
const metaImageId = metaImageIdRaw || imageId;
|
|
123
|
+
|
|
124
|
+
const getFieldValue = (fieldId) => {
|
|
125
|
+
return fields.find(field => field.field_id === fieldId)?.field_value ?? null;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const isNumeric = (val) => {
|
|
129
|
+
return typeof val === 'number' ||
|
|
130
|
+
(typeof val === 'string' && val.trim() !== '' && !isNaN(val));
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const resolveValue = async (value, fieldType) => {
|
|
134
|
+
if (!isNumeric(value)) return value;
|
|
135
|
+
|
|
136
|
+
if (fieldType === 'image') return value;
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
return await this.getContent(
|
|
140
|
+
`https://app.gudhub.com/userdata/${chapterAppId}/${value}.html`
|
|
141
|
+
);
|
|
142
|
+
} catch (e) {
|
|
143
|
+
console.error('Failed to load content:', value, e);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
let titleValue = getFieldValue(titleId);
|
|
149
|
+
let descriptionValue = getFieldValue(descriptionId);
|
|
150
|
+
let slugValue = getFieldValue(slugId);
|
|
151
|
+
let imageValue = getFieldValue(metaImageId);
|
|
152
|
+
|
|
153
|
+
[titleValue, descriptionValue, slugValue, imageValue] = await Promise.all([
|
|
154
|
+
resolveValue(titleValue, 'text'),
|
|
155
|
+
resolveValue(descriptionValue, 'text'),
|
|
156
|
+
resolveValue(slugValue, 'text'),
|
|
157
|
+
resolveValue(imageValue, 'image'),
|
|
158
|
+
]);
|
|
159
|
+
|
|
160
|
+
let imageUrl = imageValue;
|
|
161
|
+
|
|
162
|
+
if (!metaImageIdRaw) {
|
|
163
|
+
const itemFields = await gudhub.getItem(chapterAppId, chapterItemId);
|
|
164
|
+
|
|
165
|
+
const currentFieldData = itemFields?.fields?.find(
|
|
166
|
+
field => String(field?.field_id) === String(imageId)
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
if (currentFieldData?.field_value) {
|
|
170
|
+
const imageData = await gudhub.getFile(
|
|
171
|
+
chapterAppId,
|
|
172
|
+
currentFieldData.field_value
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
imageUrl = imageData?.url || imageUrl;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (metaImageIdRaw && imageUrl) {
|
|
180
|
+
const protocol = window.MODE === 'production' ? 'https' : 'http';
|
|
181
|
+
const website = window.getConfig()?.website;
|
|
182
|
+
imageUrl = `${protocol}://${website}${imageUrl}`
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// TITLE
|
|
186
|
+
if (!document.querySelector('title')) {
|
|
115
187
|
const title = document.createElement('title');
|
|
116
188
|
title.innerText = titleValue;
|
|
117
189
|
document.querySelector('head').prepend(title);
|
|
118
190
|
}
|
|
119
191
|
|
|
120
|
-
if (
|
|
192
|
+
if (!document.querySelector('[property="og:site_name"]')) {
|
|
121
193
|
const metaSiteName = document.createElement('meta');
|
|
122
194
|
metaSiteName.setAttribute('property', 'og:site_name');
|
|
123
195
|
metaSiteName.setAttribute('content', generalInfo.name);
|
|
124
196
|
document.querySelector('head').prepend(metaSiteName);
|
|
125
197
|
}
|
|
126
198
|
|
|
127
|
-
|
|
128
|
-
if ( !document.querySelector('[name="twitter:card"]') ) {
|
|
199
|
+
if (!document.querySelector('[name="twitter:card"]')) {
|
|
129
200
|
const metaCard = document.createElement('meta');
|
|
130
201
|
metaCard.setAttribute('name', 'twitter:card');
|
|
131
202
|
metaCard.setAttribute('content', 'summary_large_image');
|
|
132
203
|
document.querySelector('head').prepend(metaCard);
|
|
133
204
|
}
|
|
134
205
|
|
|
135
|
-
if (
|
|
206
|
+
if (!document.querySelector('[name="twitter:site"]') && generalInfo.twitterName) {
|
|
136
207
|
const metaSite = document.createElement('meta');
|
|
137
208
|
metaSite.setAttribute('name', 'twitter:site');
|
|
138
209
|
metaSite.setAttribute('content', generalInfo.twitterName);
|
|
139
210
|
document.querySelector('head').prepend(metaSite);
|
|
140
211
|
}
|
|
141
|
-
|
|
142
212
|
|
|
143
|
-
if (
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
213
|
+
if (!document.querySelector('[name="twitter:image"]')) {
|
|
214
|
+
const twitterMetaSiteImage = document.createElement('meta');
|
|
215
|
+
twitterMetaSiteImage.setAttribute('name', 'twitter:image');
|
|
216
|
+
twitterMetaSiteImage.setAttribute('content', imageUrl);
|
|
217
|
+
document.querySelector('head').prepend(twitterMetaSiteImage);
|
|
218
|
+
}
|
|
150
219
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
220
|
+
if (!document.querySelector('[property="og:image"]')) {
|
|
221
|
+
const metaSiteImage = document.createElement('meta');
|
|
222
|
+
metaSiteImage.setAttribute('property', 'og:image');
|
|
223
|
+
metaSiteImage.setAttribute('content', imageUrl);
|
|
224
|
+
document.querySelector('head').prepend(metaSiteImage);
|
|
157
225
|
}
|
|
158
226
|
|
|
159
|
-
if (
|
|
227
|
+
if (!document.querySelector('[property="og:type"]')) {
|
|
160
228
|
const metaWebsite = document.createElement('meta');
|
|
161
229
|
metaWebsite.setAttribute('property', 'og:type');
|
|
162
230
|
metaWebsite.setAttribute('content', 'website');
|
|
163
231
|
document.querySelector('head').prepend(metaWebsite);
|
|
164
232
|
}
|
|
165
233
|
|
|
166
|
-
if (
|
|
234
|
+
if (!document.querySelector('[property="og:locale"]')) {
|
|
167
235
|
const metaLocale = document.createElement('meta');
|
|
168
236
|
metaLocale.setAttribute('property', 'og:locale');
|
|
169
237
|
metaLocale.setAttribute('content', document.documentElement.lang);
|
|
170
238
|
document.querySelector('head').prepend(metaLocale);
|
|
171
239
|
}
|
|
172
240
|
|
|
173
|
-
if (
|
|
174
|
-
const meta = document.createElement('meta');
|
|
175
|
-
meta.setAttribute('property', 'og:title');
|
|
176
|
-
meta.setAttribute('content', titleValue);
|
|
177
|
-
document.querySelector('head').prepend(meta);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if ( !document.querySelector('[property="og:description"]') ) {
|
|
241
|
+
if (!document.querySelector('[property="og:description"]')) {
|
|
181
242
|
const metaDescription = document.createElement('meta');
|
|
182
243
|
metaDescription.setAttribute('property', 'og:description');
|
|
183
244
|
metaDescription.setAttribute('content', descriptionValue);
|
|
184
245
|
document.querySelector('head').prepend(metaDescription);
|
|
185
246
|
}
|
|
186
247
|
|
|
187
|
-
if (
|
|
248
|
+
if (!document.querySelector('[name="twitter:title"]')) {
|
|
188
249
|
const metaTwitter = document.createElement('meta');
|
|
189
250
|
metaTwitter.setAttribute('name', 'twitter:title');
|
|
190
251
|
metaTwitter.setAttribute('content', titleValue);
|
|
191
252
|
document.querySelector('head').prepend(metaTwitter);
|
|
192
253
|
}
|
|
193
254
|
|
|
194
|
-
if (
|
|
255
|
+
if (!document.querySelector('[name="twitter:description"]')) {
|
|
195
256
|
const metaTwitterDescription = document.createElement('meta');
|
|
196
257
|
metaTwitterDescription.setAttribute('name', 'twitter:description');
|
|
197
258
|
metaTwitterDescription.setAttribute('content', descriptionValue);
|
|
198
259
|
document.querySelector('head').prepend(metaTwitterDescription);
|
|
199
260
|
}
|
|
200
261
|
|
|
201
|
-
if (
|
|
262
|
+
if (!document.querySelector('[name="description"]')) {
|
|
202
263
|
const metaSimpleDescription = document.createElement('meta');
|
|
203
264
|
metaSimpleDescription.setAttribute('name', 'description');
|
|
204
265
|
metaSimpleDescription.setAttribute('content', descriptionValue);
|
|
205
266
|
document.querySelector('head').prepend(metaSimpleDescription);
|
|
206
267
|
}
|
|
207
268
|
|
|
208
|
-
|
|
209
|
-
|
|
269
|
+
if (this.og) {
|
|
270
|
+
if (this.type != 'meta_image_src') {
|
|
210
271
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
272
|
+
}
|
|
273
|
+
} else if (this.twitter) {
|
|
274
|
+
if (this.type != 'meta_image_src') {
|
|
275
|
+
|
|
276
|
+
}
|
|
216
277
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
278
|
+
} else {
|
|
279
|
+
const meta = document.createElement('meta');
|
|
280
|
+
let name;
|
|
281
|
+
if (this.type == "title") {
|
|
282
|
+
name = "title"
|
|
283
|
+
} else if (this.type == "meta_image_src") {
|
|
284
|
+
name = "image"
|
|
285
|
+
} else {
|
|
286
|
+
name = this.type
|
|
287
|
+
}
|
|
288
|
+
meta.setAttribute('name', name);
|
|
289
|
+
meta.setAttribute('content', value);
|
|
290
|
+
document.querySelector('head').prepend(meta);
|
|
291
|
+
}
|
|
231
292
|
|
|
232
293
|
this.remove();
|
|
233
294
|
}
|
|
234
295
|
|
|
235
296
|
getContent(link) {
|
|
236
|
-
return
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
297
|
+
return fetch(link)
|
|
298
|
+
.then(res => res.text())
|
|
299
|
+
.then(content => {
|
|
300
|
+
const div = document.createElement('div');
|
|
301
|
+
div.innerHTML = content;
|
|
302
|
+
return div.innerText;
|
|
303
|
+
})
|
|
304
|
+
.catch(err => {
|
|
305
|
+
console.error('getContent error:', err);
|
|
306
|
+
return null;
|
|
307
|
+
});
|
|
243
308
|
}
|
|
244
309
|
}
|
|
245
310
|
|
|
246
|
-
window.customElements.define('meta-tag', MetaTag);
|
|
311
|
+
window.customElements.define('meta-tag', MetaTag);
|