diff --git a/src/routes/sitemap.xml/+server.ts b/src/routes/sitemap.xml/+server.ts index 7481a275..50039cb6 100644 --- a/src/routes/sitemap.xml/+server.ts +++ b/src/routes/sitemap.xml/+server.ts @@ -1,8 +1,8 @@ -const pages = [ - { title: "/sitemaps/sitemap1.xml" }, - { title: "/sitemaps/sitemap2.xml" } -]; +const N = 100; // Change this value as needed +const sitemapPages = Array?.from({ length: N }, (_, i) => ({ + title: `/sitemaps/sitemap${i + 1}.xml` +})); const website = "https://stocknear.com"; @@ -24,7 +24,7 @@ export async function GET({ locals }) { - const body = sitemap(pages); + const body = sitemap(sitemapPages); const response = new Response(body); response.headers.set("Content-Type", "application/xml"); return response; @@ -35,7 +35,7 @@ const defaultStaticPageSettings = { changefreq: "daily", priority: "1.0" }; -const sitemap = (pages) => ` +const sitemap = (sitemapPages) => ` ` xmlns:image="https://www.google.com/schemas/sitemap-image/1.1" xmlns:video="https://www.google.com/schemas/sitemap-video/1.1" > - ${pages + ${sitemapPages ?.map((page) => { const loc = `${website}${page.title}`; const settings = defaultStaticPageSettings; diff --git a/src/routes/sitemaps/[slug]/+server.ts b/src/routes/sitemaps/[slug]/+server.ts index 52ace5fb..5cd14f46 100644 --- a/src/routes/sitemaps/[slug]/+server.ts +++ b/src/routes/sitemaps/[slug]/+server.ts @@ -72,6 +72,11 @@ const pages = [ { title: "/dark-pool-flow" }, ]; +const N = 100; // Change this value as needed +const sitemapPages = Array.from({ length: N }, (_, i) => ({ + title: `/sitemaps/sitemap${i + 1}.xml` +})); + const website = "https://stocknear.com"; // Helper function to create an XML URL element with optional SEO tags. @@ -86,58 +91,6 @@ const createUrlElement = (loc, { lastmod, changefreq, priority } = {}) => { `; }; -/** @type {import('./$types').RequestHandler} */ -export async function GET({ params, locals }) { - const { apiKey, apiURL, pb } = locals; - - const rawData = await fetch(apiURL + "/full-searchbar", { - method: "GET", - headers: { - "Content-Type": "application/json", - "X-API-KEY": apiKey, - }, - }); - - const outputStocks = await rawData.json(); - const stocks = outputStocks?.map((item) => ({ - id: item?.symbol, - type: item?.type, - })); - - const articles = await pb.collection("articles").getFullList({ - sort: "-created", - }); - - const tutorials = await pb.collection("tutorials").getFullList({ - sort: "-created", - }); - - // Split stocks into two halves. - const half = Math.ceil(stocks.length / 2); - let chosenStocks, chosenArticles, chosenPages, chosenTutorials; - - if (params.slug === 'sitemap1.xml') { - // Sitemap1 shows pages, articles, tutorials, and the first half of stocks. - chosenPages = pages; - chosenArticles = articles; - chosenTutorials = tutorials; - chosenStocks = stocks.slice(0, half); - } else if (params.slug === 'sitemap2.xml') { - // Sitemap2 shows only the second half of stocks. - chosenPages = []; - chosenArticles = []; - chosenTutorials = []; - chosenStocks = stocks.slice(half); - } else { - return new Response("Not Found", { status: 404 }); - } - - const body = sitemap(chosenStocks, chosenArticles, chosenPages, chosenTutorials); - const response = new Response(body); - response.headers.set("Content-Type", "application/xml"); - return response; -} - // Default settings for different content types. const defaultStaticPageSettings = { changefreq: "weekly", priority: "0.8" }; const homePageSettings = { changefreq: "daily", priority: "1.0" }; @@ -146,10 +99,106 @@ const tutorialSettings = { changefreq: "daily", priority: "0.7" }; const stockSettings = { changefreq: "daily", priority: "0.6" }; // Define extra subdirectories for stocks. -const stockExtraSubPaths = ["/financials", "/financials/balance-sheet","/financials/cash-flow","/financials/ratios","/statistics","/statistics/market-cap","/statistics/revenue","/statistics/price-reaction","/statistics/fail-to-deliver","/metrics","/forecast","/forecast/analyst","/forecast/ai","/dark-pool","/options","/options/unusual-activity","/options/hottest-contracts","/options/volatility","/options/oi","/insider","/dividends","/history","/profile","/profile/employees"]; -const etfExtraSubPaths = ["/holdings","/dark-pool","/options","/options/unusual-activity","/options/hottest-contracts","/options/volatility","/options/oi","/insider","/dividends","/history"]; +const stockExtraSubPaths = [ + "/financials", + "/financials/balance-sheet", + "/financials/cash-flow", + "/financials/ratios", + "/statistics", + "/statistics/market-cap", + "/statistics/revenue", + "/statistics/price-reaction", + "/statistics/fail-to-deliver", + "/metrics", + "/forecast", + "/forecast/analyst", + "/forecast/ai", + "/dark-pool", + "/options", + "/options/unusual-activity", + "/options/hottest-contracts", + "/options/volatility", + "/options/oi", + "/insider", + "/dividends", + "/history", + "/profile", + "/profile/employees" +]; +const etfExtraSubPaths = [ + "/holdings", + "/dark-pool", + "/options", + "/options/unusual-activity", + "/options/hottest-contracts", + "/options/volatility", + "/options/oi", + "/insider", + "/dividends", + "/history" +]; +/** @type {import('./$types').RequestHandler} */ +export async function GET({ params, locals }) { + const { apiKey, apiURL, pb } = locals; + // Fetch stocks data. + const rawData = await fetch(apiURL + "/full-searchbar", { + method: "GET", + headers: { + "Content-Type": "application/json", + "X-API-KEY": apiKey, + }, + }); + const outputStocks = await rawData.json(); + const stocks = outputStocks?.map((item) => ({ + id: item?.symbol, + type: item?.type, + })); + + // Fetch articles and tutorials. + const articles = await pb.collection("articles").getFullList({ + sort: "-created", + }); + const tutorials = await pb.collection("tutorials").getFullList({ + sort: "-created", + }); + + // Extract sitemap number from params.slug (e.g. "sitemap1.xml"). + const sitemapMatch = params.slug.match(/sitemap(\d+)\.xml/); + if (!sitemapMatch) { + return new Response("Not Found", { status: 404 }); + } + const sitemapIndex = parseInt(sitemapMatch[1], 10) - 1; + if (sitemapIndex < 0 || sitemapIndex >= sitemapPages.length) { + return new Response("Not Found", { status: 404 }); + } + + // Split the stocks array into chunks based on the number of sitemaps. + const totalSitemaps = sitemapPages.length; + const chunkSize = Math.ceil(stocks.length / totalSitemaps); + const chosenStocks = stocks.slice( + sitemapIndex * chunkSize, + (sitemapIndex + 1) * chunkSize + ); + + // Only include pages, articles, and tutorials in the first sitemap. + let chosenPages = []; + let chosenArticles = []; + let chosenTutorials = []; + if (sitemapIndex === 0) { + chosenPages = pages; + chosenArticles = articles; + chosenTutorials = tutorials; + } + + const body = sitemap(chosenStocks, chosenArticles, chosenPages, chosenTutorials); + const response = new Response(body); + response.headers.set("Content-Type", "application/xml"); + return response; +} + +// Sitemap generation function. const sitemap = (stocks, articles, pages, tutorials) => ` ` { urlElements += createUrlElement(`${website}${basePath}${ticker.id}${subPath}`, stockSettings); }); - } - else if (ticker.type === "ETF") { + } else if (ticker.type === "ETF") { etfExtraSubPaths?.forEach((subPath) => { urlElements += createUrlElement(`${website}${basePath}${ticker.id}${subPath}`, stockSettings); });