@seip/blue-bird 0.3.7 → 0.3.8

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/core/router.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import express from "express";
2
2
  import Config from "./config.js";
3
+ import Template from "./template.js";
3
4
 
4
5
  const __dirname = Config.dirname()
5
6
  const props = Config.props()
@@ -131,5 +132,96 @@ class Router {
131
132
  getPath() {
132
133
  return this.path
133
134
  }
135
+
136
+ /**
137
+ * Registers multiple routes based on an SEO configuration array.
138
+ * Supports both multi-language (e.g., en, es keys) and single-language (meta key) formats.
139
+ *
140
+ * @param {Array<Object>} routesConfig - Array of route objects.
141
+ * @param {Object} [options={}] - Configuration options.
142
+ * @param {Array<string>} [options.languages] - List of languages to register (e.g., ["en", "es"]).
143
+ * @param {string} [options.defaultLanguage="en"] - The default language for the base path.
144
+ * @param {Function} [options.templateRenderer] - Optional custom template renderer (defaults to Template.renderReact).
145
+ *
146
+ * @example
147
+ * router.seo([
148
+ * {
149
+ * path: "/",
150
+ * component: "Home",
151
+ * meta: { titleMeta: "Home - Blue Bird", descriptionMeta: "Welcome to Blue Bird" },
152
+ * props: { id: 1, name: "Name 1" }
153
+ * },
154
+ * {
155
+ * path: "/about",
156
+ * component: "About",
157
+ * meta: { titleMeta: "About - Blue Bird", descriptionMeta: "About blue bird" },
158
+ * props: { id: 2, name: "Name 2" }
159
+ * }
160
+ * ], { languages: ["en", "es"], defaultLanguage: "en" });
161
+ */
162
+ seo(routesConfig, options = {}) {
163
+ const {
164
+ languages = [],
165
+ defaultLanguage = "en",
166
+ templateRenderer
167
+ } = options;
168
+
169
+ const render = templateRenderer || ((res, component, props, renderOptions) => {
170
+ return Template.renderReact(res, component, props, renderOptions);
171
+ });
172
+
173
+ routesConfig.forEach(route => {
174
+ const { path, component, props = {}, meta = {} } = route;
175
+
176
+ if (Object.keys(meta).length > 0 || route.titleMeta) {
177
+ this.get(path, (req, res) => {
178
+ const dynamicProps = {
179
+ props: {
180
+ ...props,
181
+ params: req.params,
182
+ query: req.query
183
+ }
184
+ };
185
+ return render(res, component, dynamicProps, {
186
+ metaTags: meta.titleMeta ? meta : {
187
+ titleMeta: route.titleMeta || meta.title,
188
+ descriptionMeta: route.descriptionMeta || meta.description || meta.desc,
189
+ keywordsMeta: route.keywordsMeta || meta.keywords,
190
+ }
191
+ });
192
+ });
193
+ }
194
+
195
+ const detectedLanguages = languages.length > 0
196
+ ? languages
197
+ : Object.keys(route).filter(key => key.length === 2);
198
+
199
+ detectedLanguages.forEach(lang => {
200
+ if (typeof route[lang] === "object") {
201
+ const langData = route[lang];
202
+ const isDefault = lang === defaultLanguage;
203
+ const langPath = isDefault ? path : `/${lang}${path === "/" ? "" : path}`;
204
+
205
+ this.get(langPath, (req, res) => {
206
+ const dynamicProps = {
207
+ props: {
208
+ ...props,
209
+ params: req.params,
210
+ query: req.query
211
+ }
212
+ };
213
+ return render(res, component, dynamicProps, {
214
+ metaTags: {
215
+ titleMeta: langData.title || langData.titleMeta,
216
+ descriptionMeta: langData.desc || langData.description || langData.descriptionMeta,
217
+ keywordsMeta: langData.keywords || langData.keywordsMeta,
218
+ langMeta: lang
219
+ }
220
+ });
221
+ });
222
+ }
223
+ });
224
+ });
225
+ }
134
226
  }
135
227
  export default Router;
package/core/template.js CHANGED
@@ -149,6 +149,10 @@ class Template {
149
149
  ...metaTags
150
150
  }
151
151
 
152
+ if (metaTags.langMeta && !options.langHtml) {
153
+ langHtml = metaTags.langMeta;
154
+ }
155
+
152
156
  res.type("text/html");
153
157
  res.status(200);
154
158
  const cacheKey = `${component}_${metaTags.titleMeta}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seip/blue-bird",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Express + React opinionated framework with SPA or API architecture and built-in JWT auth",
5
5
  "type": "module",
6
6
  "bin": {