恢复Nav客户端版以便ISR模式下不受影响增加新建记录时自动更新sitemap

This commit is contained in:
jingrow 2025-06-24 16:46:48 +08:00
parent 71e3b90a6b
commit c70b262ec2
6 changed files with 480 additions and 69 deletions

26
app/api/sitemap/route.js Normal file
View File

@ -0,0 +1,26 @@
// app/api/sitemap/route.js
import { getAllSlugs } from '@/utils/data';
import fs from 'fs';
import path from 'path';
export async function POST(req) {
const secret = req.headers.get('x-revalidate-secret');
if (secret !== process.env.REVALIDATE_TOKEN) {
return new Response('Unauthorized', { status: 401 });
}
const slugs = await getAllSlugs();
const siteUrl = process.env.SITE_URL || 'https://yourdomain.com';
const urls = slugs.map(slugArr => '/' + slugArr.join('/'));
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(url => `
<url>
<loc>${siteUrl}${url}</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
`).join('')}
</urlset>`;
fs.writeFileSync(path.join(process.cwd(), 'public/sitemap.xml'), sitemap, 'utf8');
return new Response('Sitemap regenerated', { status: 200 });
}

122
components/headers/Nav.jsx Normal file
View File

@ -0,0 +1,122 @@
"use client";
import Link from "next/link";
import React, { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
// !text-[var(--current-color)]
export default function Nav({ color = "#fab758" }) {
const [menu, setMenu] = useState([]);
const pathname = usePathname();
useEffect(() => {
// Dynamically import Bootstrap
import("bootstrap").then((Bootstrap) => {
const CLASS_NAME = "has-child-dropdown-show";
// Save the original toggle function
const originalToggle = Bootstrap.Dropdown.prototype.toggle;
// Override the toggle function
Bootstrap.Dropdown.prototype.toggle = function () {
// Remove the CLASS_NAME from all dropdowns
document.querySelectorAll("." + CLASS_NAME).forEach(function (e) {
e.classList.remove(CLASS_NAME);
});
// Traverse up through the closest dropdown parents
let dd = this._element
.closest(".dropdown")
.parentNode.closest(".dropdown");
for (; dd && dd !== document; dd = dd.parentNode.closest(".dropdown")) {
dd.classList.add(CLASS_NAME);
}
// Call the original toggle function
return originalToggle.call(this);
};
// Add event listeners for hide.bs.dropdown to remove the CLASS_NAME
document.querySelectorAll(".dropdown").forEach(function (dd) {
dd.addEventListener("hide.bs.dropdown", function (e) {
if (this.classList.contains(CLASS_NAME)) {
this.classList.remove(CLASS_NAME);
e.preventDefault();
}
e.stopPropagation();
});
});
});
//
fetch("/api/get-menu")
.then((res) => res.json())
.then((data) => setMenu(data.menu || []));
// Optional cleanup function for any potential side effects
return () => {
// Cleanup code here (if needed)
};
}, []);
// position
const filterHeaderMenu = (items) => {
return items.filter(item => item.position === 'Header');
};
//
const renderMenu = (items, level = 0) => {
// position
if (level === 0) items = filterHeaderMenu(items);
return items.map((item) => {
const hasChildren = item.children && item.children.length > 0;
const hasHref = !!item.href && item.href !== "#";
if (hasChildren) {
return (
<li key={item.id} className={`nav-item dropdown${level > 0 ? " dropdown-submenu dropend" : ""}`}>
<div style={{ display: 'flex', alignItems: 'center' }}>
{/* 如果有href左侧为可点击跳转始终用当前item的href */}
{hasHref && (
<Link
className={`${level > 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${pathname === item.href ? "!text-[var(--current-color)]" : ""}`}
href={item.href}
style={{ paddingRight: 0 }}
>
{item.label}
</Link>
)}
{/* 右侧小三角,负责展开下拉 */}
<a
className={`${hasHref ? "dropdown-toggle" : (level > 0 ? "dropdown-item" : "nav-link") + " dropdown-toggle"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${!hasHref && pathname === item.href ? "!text-[var(--current-color)]" : ""}`}
href="#"
data-bs-toggle="dropdown"
aria-expanded="false"
style={hasHref ? { paddingLeft: 8, minWidth: 24 } : {}}
>
{hasHref ? <span className="sr-only">展开</span> : item.label}
</a>
</div>
<ul className={`dropdown-menu${level > 0 ? " submenu" : ""}`}>
{renderMenu(item.children, level + 1)}
</ul>
</li>
);
} else {
return (
<li key={item.id} className="nav-item">
<Link
className={`${level > 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)] ${pathname === item.href ? "!text-[var(--current-color)]" : ""}`}
href={item.href || "#"}
>
{item.label}
</Link>
</li>
);
}
});
};
return (
<ul className="navbar-nav" style={{ "--current-color": color }}>
{renderMenu(menu)}
</ul>
);
}

View File

@ -1,62 +0,0 @@
import Link from "next/link";
import React from "react";
export default function NavUI({ menu = [], color = "#fab758" }) {
const filterHeaderMenu = (items) => {
return items.filter(item => item.position === 'Header');
};
const renderMenu = (items, level = 0) => {
if (level === 0) items = filterHeaderMenu(items);
return items.map((item) => {
const hasChildren = item.children && item.children.length > 0;
const hasHref = !!item.href && item.href !== "#";
if (hasChildren) {
return (
<li key={item.id} className={`nav-item dropdown${level > 0 ? " dropdown-submenu dropend" : ""}`}>
<div style={{ display: 'flex', alignItems: 'center' }}>
{hasHref && (
<Link
className={`${level > 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)]`}
href={item.href}
style={{ paddingRight: 0 }}
>
{item.label}
</Link>
)}
<a
className={`${hasHref ? "dropdown-toggle" : (level > 0 ? "dropdown-item" : "nav-link") + " dropdown-toggle"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)]`}
href="#"
data-bs-toggle="dropdown"
aria-expanded="false"
style={hasHref ? { paddingLeft: 8, minWidth: 24 } : {}}
>
{hasHref ? <span className="sr-only">展开</span> : item.label}
</a>
</div>
<ul className={`dropdown-menu${level > 0 ? " submenu" : ""}`}>
{renderMenu(item.children, level + 1)}
</ul>
</li>
);
} else {
return (
<li key={item.id} className="nav-item">
<Link
className={`${level > 0 ? "dropdown-item" : "nav-link"} !text-[.7rem] !tracking-[normal] hover:!text-[var(--current-color)] after:!text-[var(--current-color)]`}
href={item.href || "#"}
>
{item.label}
</Link>
</li>
);
}
});
};
return (
<ul className="navbar-nav" style={{ "--current-color": color }}>
{renderMenu(menu)}
</ul>
);
}

View File

@ -1,7 +0,0 @@
import { getMenuData } from '@/utils/data';
import NavUI from './NavUI';
export default async function Nav(props) {
const { menu } = await getMenuData();
return <NavUI menu={menu} {...props} />;
}

4
public/robots.txt Normal file
View File

@ -0,0 +1,4 @@
User-agent: *
Disallow:
Sitemap: /sitemap.xml

328
public/sitemap.xml Normal file
View File

@ -0,0 +1,328 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/organic-water-soluble-and-non-toxic-food-pigment-extracted-and-processed-from-spirulina-platensis-spirulina-blue-spirulina-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/ratio-extract/organic-bladderwrack-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/ratio-extract/organic-white-kidney-bean-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-cordyceps-militaris-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-best-price-organic-freeze-dried-organic-pure-goji-berry-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-extract-natural-pigment-fruit-powder-organic-raspberry-powder-green-pure-powder-extract-powder-food-grade-organic</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/test007</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/vegetable-powders/organic-organic-super-green-powder-supply-food-gradevegetable-powder-wheatgrass-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/news</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/vegetable-powders/organic-vegetable-powder-spinach-extract-powder-organic-pure-quality</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/ratio-extract/organic-burdock-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/test005</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-supply-food-grade-powder-best-price-organic-raspberry-powder-quality-food-grade-powder-100-pure-fruit-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-turkey-tail-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-tremella-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/vegetable-powders/organic-good-quality-plant-extract-natural-pigment-vegetablepowder-freeze-dried-organic-pure-water-kale-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/ratio-extract/organic-schisandra-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/vegetable-powders/organic-vegetable-seasoning-powder-freeze-dried-organic-pure-quality-barley-grass-powde</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-maitake-mushroom-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-100-pure-fruit-powder-instant-filled-powder-mango-powder-freeze-dried-extract-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/sub-category</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/ratio-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/vegetable-powders/organic-plant-extract-good-quality-beetroot-red-colour-powder-beetroot-juice-powder-beetroot-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-enoki-mushroom-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-freeze-dried-organic-pure-good-quality-organic-strawberry-powder-extract-natural-pigment-fruit-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/Test003</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/project001</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-healthy-without-pesticide-residues-fruit-fiber-organic-super-freeze-dried-organic-pure-water-fruit-powder-organic-orange-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-chaga-mushroom-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/test001</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-oyster-mushroom-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/vegetable-powders</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/organic-cbd-full-spectrum-pure-thc-free-high-quality-no-pesticide-residue-no-heavy-metal-residue-cbd-distillated-oil-refined-oil</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-chaga-mushroom-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/test006</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-organic-lions-mane-mushroom-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/news/test-news</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/ratio-extract/organic-ashwagandha-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-organic-pure-quality-best-price-organic-supply-fruit-grade-powder-cranberry-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/ratio-extract/organic-tribulus-terrestris-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/test004</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/algae-extract/test002</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/about</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/contact</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/vegetable-powders/organic-best-price-organic-supply-vegetable-grade-powder-100pure-green-vegetable-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/page001</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/test1</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/mushroom-extracts/organic-snow-mushroom-extract</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-fruit-fiber-organic-super-powder-organic-pure-quality-freeze-dried-extract-blueberry-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://192.168.2.200:3001/products/fruit-powders/organic-organic-powder-extract-supply-food-grade-freeze-dried-pomegranate-extract-powder</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
</urlset>