#Continue of sitemap

1 messages · Page 1 of 1 (latest)

crimson yacht
#

<@&1089670008898080870>

export default async function handler(req, res) {
// Generate your sitemap
await generateSitemap();

// Read the generated sitemap file
const sitemap = fs.readFileSync(
path.join(__dirname, "../../app/sitemap.ts"),
"utf8"
);

// Set the appropriate headers
res.statusCode = 200;
res.setHeader("Content-Type", "text/xml");
res.setHeader("Cache-control", "stale-while-revalidate, s-maxage=3600");

// Send the response
res.end(sitemap);
}

We are using the app router version of API (Nextjs14)
So I think no more req, res?
Directly using GET/POST

viscid wolfBOT
#

Hi @crimson yacht. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Yes, you're correct. In Next.js 14, with the introduction of the App Router, you can use HTTP method names directly as function names instead of using the traditional req, res pattern. Here's how you can modify your code:

import { NextResponse } from "next/server";
import fs from 'fs';
import path from 'path';
import { generateSitemap } from './your-sitemap-generator';

export async function GET() {
  // Generate your sitemap
  await generateSitemap();

  // Read the generated sitemap file
  const sitemap = fs.readFileSync(
    path.join(__dirname, "../../app/sitemap.ts"),
    "utf8"
  );

  // Create a new NextResponse and set the appropriate headers
  const response = new NextResponse(sitemap)
    .withHeader("Content-Type", "text/xml")
    .withHeader("Cache-control", "stale-while-revalidate, s-maxage=3600");

  // Return the response
  return response;
}

In this code, GET is an async function that handles GET requests to your API route. It uses the NextResponse class from next/server to create a response, set headers, and send the response.

Please note that you need to replace './your-sitemap-generator' with the actual path to your generateSitemap function.

This information is based on the extract from Github Issue (closed): Server doesn't dynamically load pages/api routes without manual restart > Comments (https://github.com/vercel/next.js/issues/55672).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crimson yacht kapa.ai is still learning and improving, please let us know how it did by reacting below

crimson yacht
#

@viscid wolf

import { NextResponse } from "next/server";
import path from "path";
import generateSitemap from "../../scripts/sitemap-generation";

export async function GET() {
// Generate your sitemap
await generateSitemap();

// Read the generated sitemap file
const sitemap = fs.readFileSync(
path.join(__dirname, "../../app/sitemap.ts"),
"utf8"
);

// Create a new NextResponse and set the appropriate headers
const response = new NextResponse(sitemap)
.withHeader("Content-Type", "text/xml")
.withHeader("Cache-control", "stale-while-revalidate, s-maxage=3600");

// Return the response
return response;
}

For context this is my generatesitemap:
require("dotenv").config({ path: ".env.local" });

const fs = require("fs");
const path = require("path");
const contentful = require("contentful");

const client = contentful.createClient({
space: process.env.NEXT_PUBLIC_CONTENTFUL_SPACE_ID,
accessToken: process.env.NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN,
});

// Helper function to format dates
const formatDate = (date) => {
const d = new Date(date);
return ${d.getFullYear()}-${(d.getMonth() + 1) .toString() .padStart(2, "0")}-${d.getDate().toString().padStart(2, "0")};
};

async function generateSitemap() {
try {
// Static URLs for your site
const staticUrls = [
{
url: "/",
lastModified: new Date("2023-12-21"),
changeFrequency: "yearly",
priority: 1.0,
},
{
url: "/jasa-pengiriman-china-indonesia-laut",
lastModified: new Date("2023-12-21"),
changeFrequency: "yearly",
priority: 0.8,
},
{
url: "/jasa-pengiriman-china-indonesia-udara",
lastModified: new Date("2023-12-21"),
changeFrequency: "monthly",
priority: 0.8,
},
{
url: "/jasa-belanja-dari-china",
lastModified: new Date("2023-12-21"),
changeFrequency: "monthly",
priority: 0.8,
},
{
url: "/blog",
lastModified: new Date("2023-12-21"),
changeFrequency: "weekly",
priority: 0.8,
},
{
url: "/tracking",
lastModified: new Date("2023-12-21"),
changeFrequency: "monthly",
priority: 0.8,
},
];

// Fetch dynamic blog post URLs from Contentful
const response = await client.getEntries({
  content_type: "blogPost",
  select: "fields.slug,sys.updatedAt",
});

// Prepare sitemap array
let sitemapArray = staticUrls.map((url) => ({
  url: `https://emporiumcargo.com${url.url}`,
  lastModified: formatDate(url.lastModified),
  changeFrequency: url.changeFrequency,
  priority: url.priority,
}));

// Add dynamic URLs from Contentful
response.items.forEach((item) => {
  sitemapArray.push({
    url: `https://emporiumcargo.com/blog/${item.fields.slug}`,
    lastModified: item.sys.updatedAt
      ? formatDate(item.sys.updatedAt)
      : "2023-01-01",
    changeFrequency: "weekly",
    priority: 0.8,
  });
});

// Generate TypeScript code
let tsCode = `import { MetadataRoute } from "next";\n\nexport default function sitemap(): MetadataRoute.Sitemap {\n  return [\n`;
sitemapArray.forEach((item) => {
  tsCode += `    {\n      url: "${item.url}",\n      lastModified: "${item.lastModified}",\n      changeFrequency: "${item.changeFrequency}",\n      priority: ${item.priority}\n    },\n`;
});
tsCode += `  ];\n}\n`;

// Write to sitemap.ts file
const sitemapPath = path.join(__dirname, "../sitemap.ts");
fs.writeFileSync(sitemapPath, tsCode);
console.log("Sitemap TS file generated successfully.");

} catch (error) {
console.error("Error generating sitemap TS file:", error);
}
}

// generateSitemap();

module.exports = generateSitemap;

Can you update this code to make it proper?

Right now i am getting:
Property 'withHeader' does not exist on type

viscid wolfBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The error you're encountering is because withHeader is not a method on NextResponse. Instead, you should use the headers method to set headers on the response. Here's how you can modify your code:

import { NextResponse } from "next/server";
import fs from 'fs';
import path from 'path';
import generateSitemap from "../../scripts/sitemap-generation";

export async function GET() {
  // Generate your sitemap
  await generateSitemap();

  // Read the generated sitemap file
  const sitemap = fs.readFileSync(
    path.join(__dirname, "../../app/sitemap.ts"),
    "utf8"
  );

  // Create a new NextResponse and set the appropriate headers
  const response = new NextResponse(sitemap)
    .headers({
      "Content-Type": "text/xml",
      "Cache-control": "stale-while-revalidate, s-maxage=3600"
    });

  // Return the response
  return response;
}

In this code, headers is a method on NextResponse that accepts an object where the keys are the header names and the values are the header values.

This information is based on the extract from Github Issue (closed): Server doesn't dynamically load pages/api routes without manual restart > Comments (https://github.com/vercel/next.js/issues/55672).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@crimson yacht kapa.ai is still learning and improving, please let us know how it did by reacting below

crimson yacht
#

@viscid wolf

import { NextResponse } from "next/server";
import fs from "fs";
import path from "path";
import generateSitemap from "../../scripts/sitemap-generation";

export async function GET() {
// Generate your sitemap
await generateSitemap();

// Read the generated sitemap file
const sitemap = fs.readFileSync(
path.join(__dirname, "../../app/sitemap.ts"),
"utf8"
);

// Create a new NextResponse and set the appropriate headers
const response = new NextResponse(sitemap).headers({
"Content-Type": "text/xml",
"Cache-control": "stale-while-revalidate, s-maxage=3600",
});

// Return the response
return response;
}

This expression is not callable.
Type 'Headers' has no call signatures.ts(2349)

viscid wolfBOT
#

Let me check the knowledge base for you. One moment! :books:

#

I apologize for the confusion. The headers method on NextResponse is a getter, not a function, so it cannot be called like a function. Instead, you should use the NextResponse.rewrite() method to create a new response with the desired headers. Here's how you can modify your code:

import { NextResponse } from "next/server";
import fs from 'fs';
import path from 'path';
import generateSitemap from "../../scripts/sitemap-generation";

export async function GET() {
  // Generate your sitemap
  await generateSitemap();

  // Read the generated sitemap file
  const sitemap = fs.readFileSync(
    path.join(__dirname, "../../app/sitemap.ts"),
    "utf8"
  );

  // Create a new NextResponse and set the appropriate headers
  const response = NextResponse.rewrite(sitemap).headers({
    "Content-Type": "text/xml",
    "Cache-control": "stale-while-revalidate, s-maxage=3600",
  });

  // Return the response
  return response;
}

In this code, NextResponse.rewrite() is used to create a new response with the given body, and then the headers getter is used to set the headers on the response.

This information is based on the extract from Github Issue (closed): Server doesn't dynamically load pages/api routes without manual restart > Comments (https://github.com/vercel/next.js/issues/55672).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: