diff --git a/docusaurus.config.js b/docusaurus.config.js
index e465d14e..3e139d38 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -1154,6 +1154,7 @@ const config = {
sitemap: {
changefreq: "weekly",
priority: 0.5,
+ lastmod: "date",
ignorePatterns: [
"/docs/graphql-reference/**",
"/markdown-page/**",
diff --git a/nginx/default.conf b/nginx/default.conf
index ee2ff42c..71a7c7ed 100644
--- a/nginx/default.conf
+++ b/nginx/default.conf
@@ -5,6 +5,10 @@ server {
root /usr/share/nginx/html;
index index.html;
+ # Behind TLS termination nginx sees plain http; emit relative Location headers
+ # so 301s keep the client's https scheme (no extra http->https upgrade hop).
+ absolute_redirect off;
+
# --- Compression (WP-0.1) ---
# The base image gzips text/html only; add JS/CSS/SVG/JSON so bundles ship
# compressed. Brotli is intentionally NOT enabled: nginx:stable-alpine ships
diff --git a/plugins/tech-article-jsonld.js b/plugins/tech-article-jsonld.js
index 74377b43..a8d43270 100644
--- a/plugins/tech-article-jsonld.js
+++ b/plugins/tech-article-jsonld.js
@@ -69,33 +69,6 @@ function gitDate(siteDir, filePath, first) {
}
}
-function humanize(seg) {
- return seg
- .replace(/[-_]+/g, " ")
- .replace(/\b\w/g, (c) => c.toUpperCase());
-}
-
-function breadcrumb(base, permalink, title) {
- const parts = permalink.split("/").filter(Boolean); // e.g. ["docs","blockchain","Solana","x"]
- const items = [];
- let acc = "";
- parts.forEach((seg, i) => {
- acc += `/${seg}`;
- const isLast = i === parts.length - 1;
- items.push({
- "@type": "ListItem",
- position: i + 1,
- name: isLast ? title || humanize(seg) : seg === "docs" ? "Docs" : humanize(seg),
- item: `${base}${acc}/`,
- });
- });
- return {
- "@context": "https://schema.org",
- "@type": "BreadcrumbList",
- itemListElement: items,
- };
-}
-
/** @type {import('@docusaurus/types').PluginModule} */
module.exports = function techArticleJsonLdPlugin(context) {
return {
@@ -142,11 +115,9 @@ module.exports = function techArticleJsonLdPlugin(context) {
},
};
- const crumbs = breadcrumb(base, permalink, title);
-
- const tag =
- `` +
- ``;
+ // BreadcrumbList is emitted natively by the Docusaurus theme's breadcrumbs,
+ // so we inject only TechArticle here to avoid duplicate structured data.
+ const tag = ``;
let html = fs.readFileSync(htmlPath, "utf8");
if (html.includes('"@type":"TechArticle"')) {