Skip to content

Added revalidation docs #1444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 1, 2024
Merged

Added revalidation docs #1444

merged 3 commits into from
Nov 1, 2024

Conversation

D-K-P
Copy link
Member

@D-K-P D-K-P commented Oct 31, 2024

Summary by CodeRabbit

  • New Features

    • Enhanced Next.js setup guide with expanded troubleshooting and additional resources.
    • Introduced sections on revalidation tasks, including handlers for App Router and Pages Router.
    • Added instructions for testing revalidation tasks with examples.
  • Documentation

    • Updated import statements and corrected typos in the guide.

Copy link

changeset-bot bot commented Oct 31, 2024

⚠️ No Changeset found

Latest commit: df5cd7e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Oct 31, 2024

Walkthrough

The changes involve updates to the nextjs.mdx documentation for Trigger.dev, enhancing the Next.js setup guide. Modifications include rephrased descriptions, corrected import statements, and an expanded "Troubleshooting" section. New subsections cover revalidation tasks, including detailed instructions and code examples for both App Router and Pages Router. Additionally, a section on testing the revalidation task has been added, complete with a JSON payload example. Overall, the guide's structure is maintained while improving its comprehensiveness.

Changes

File Change Summary
docs/guides/frameworks/nextjs.mdx - Updated title, sidebar title, and description.
- Corrected import paths and added revalidation snippets.
- Expanded "Troubleshooting" to "Troubleshooting & extra resources."
- Added sections for revalidation tasks and testing, including code examples.

Possibly related PRs

Suggested reviewers

  • matt-aitken

🐇 In the garden, the changes bloom,
A guide for Next.js, dispelling the gloom.
With revalidation tasks, clear and bright,
Testing made easy, everything feels right!
So hop along, let’s spread the cheer,
For Trigger.dev's guide is now crystal clear! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (2)
docs/guides/frameworks/nextjs.mdx (2)

257-264: Consider adding security implications.

While the introduction effectively explains revalidation, it would be beneficial to add a note about security considerations. Specifically, mention that the revalidation endpoint could be a potential attack vector if not properly secured, which is why the secret token validation is crucial.


391-399: Enhance testing documentation.

Consider adding:

  1. Validation rules for the path parameter (e.g., must start with '/', no query parameters)
  2. More example payloads for common scenarios
  3. Expected responses for both success and failure cases

Add examples like:

// Example 1: Revalidate blog post
{
  "path": "blog/post-1"
}

// Example 2: Revalidate entire section
{
  "path": "products"
}

// Example responses
Success: { "revalidated": true }
Error: { "message": "Invalid secret" }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between da08e50 and 628389d.

📒 Files selected for processing (1)
  • docs/guides/frameworks/nextjs.mdx (2 hunks)
🔇 Additional comments (1)
docs/guides/frameworks/nextjs.mdx (1)

251-251: LGTM!

The expanded section title better reflects the content that includes both troubleshooting information and additional resources.

Comment on lines 265 to 293
#### Revalidation helper: App Router

If you are using the App router, create a new revalidation route at `app/api/revalidate/path/route.ts`:

```ts app/api/revalidate/path/route.ts
import { NextRequest, NextResponse } from "next/server";
import { revalidatePath } from "next/cache";

export async function POST(request: NextRequest) {
try {
const { path, type, secret } = await request.json();
// Create a REVALIDATION_SECRET and set it in your environment variables
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ message: "Invalid secret" }, { status: 401 });
}

if (!path) {
return NextResponse.json({ message: "Path is required" }, { status: 400 });
}

revalidatePath(path, type);

return NextResponse.json({ revalidated: true });
} catch (err) {
console.error("Error revalidating path:", err);
return NextResponse.json({ message: "Error revalidating path" }, { status: 500 });
}
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance error handling and documentation.

While the implementation is solid, consider these improvements:

  1. Document the optional type parameter in the request body (it can be 'page' or 'layout')
  2. Use template literals for error messages
  3. Consider adding more specific error types
- console.error("Error revalidating path:", err);
+ console.error(`Error revalidating path: ${err instanceof Error ? err.message : String(err)}`);

Also, consider adding this documentation above the code:

type RevalidateRequestBody = {
  path: string;
  type?: "page" | "layout"; // Optional parameter to specify revalidation type
  secret: string;
};

Comment on lines 295 to 326
#### Revalidation helper: Pages Router

If you are using the Pages router, create a new revalidation route at `pages/api/revalidate/path.ts`:

```ts pages/api/revalidate/path.ts
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
if (req.method !== "POST") {
return res.status(405).json({ message: "Method not allowed" });
}

const { path, secret } = req.body;

if (secret !== process.env.REVALIDATION_SECRET) {
return res.status(401).json({ message: "Invalid secret" });
}

if (!path) {
return res.status(400).json({ message: "Path is required" });
}

await res.revalidate(path);

return res.json({ revalidated: true });
} catch (err) {
console.error("Error revalidating path:", err);
return res.status(500).json({ message: "Error revalidating path" });
}
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance type safety and error handling.

Consider these improvements:

  1. Add type restriction for HTTP methods
  2. Use template literals for error messages
  3. Add more specific error types
+ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
+ interface RevalidateRequest extends NextApiRequest {
+   method: HttpMethod;
+   body: {
+     path: string;
+     secret: string;
+   };
+ }

- export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+ export default async function handler(req: RevalidateRequest, res: NextApiResponse) {

Committable suggestion was skipped due to low confidence.

Comment on lines +328 to +389
#### Revalidation task

This task takes a `path` as a payload and will revalidate the path you specify, using the handler you set up previously.

<Note>

To run this task locally you will need to set the `REVALIDATION_SECRET` environment variable in your `.env.local` file (or `.env` file if using Pages router).

To run this task in production, you will need to set the `REVALIDATION_SECRET` environment variable in Vercel, in your project settings, and also in your environment variables in the Trigger.dev dashboard.

</Note>

```ts trigger/revalidate-path.ts
import { logger, task } from "@trigger.dev/sdk/v3";

const NEXTJS_APP_URL = process.env.NEXTJS_APP_URL; // e.g. "http://localhost:3000" or "https://my-nextjs-app.vercel.app"
const REVALIDATION_SECRET = process.env.REVALIDATION_SECRET; // Create a REVALIDATION_SECRET and set it in your environment variables

export const revalidatePath = task({
id: "revalidate-path",
run: async (payload: { path: string }) => {
const { path } = payload;

try {
const response = await fetch(`${NEXTJS_APP_URL}/api/revalidate/path`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
path: `${NEXTJS_APP_URL}/${path}`,
secret: REVALIDATION_SECRET,
}),
});

if (response.ok) {
logger.log("Path revalidation successful", { path });
return { success: true };
} else {
logger.error("Path revalidation failed", {
path,
statusCode: response.status,
statusText: response.statusText,
});
return {
success: false,
error: `Revalidation failed with status ${response.status}: ${response.statusText}`,
};
}
} catch (error) {
logger.error("Path revalidation encountered an error", {
path,
error: error instanceof Error ? error.message : String(error),
});
return {
success: false,
error: `Failed to revalidate path due to an unexpected error`,
};
}
},
});
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve URL handling and environment validation.

The implementation needs some improvements:

  1. URL Construction: The current implementation might create URLs with double slashes. Use URL class instead.
  2. Environment Variables: Add validation at startup.
  3. Network Failures: Consider adding retry logic.

Apply these improvements:

+ // Validate environment variables at startup
+ if (!NEXTJS_APP_URL) {
+   throw new Error("NEXTJS_APP_URL environment variable is required");
+ }
+ if (!REVALIDATION_SECRET) {
+   throw new Error("REVALIDATION_SECRET environment variable is required");
+ }

  run: async (payload: { path: string }) => {
    const { path } = payload;

+   // Ensure clean URL construction
+   const baseUrl = new URL("/api/revalidate/path", NEXTJS_APP_URL);
+   const pathToRevalidate = new URL(path, NEXTJS_APP_URL).pathname;

    try {
-     const response = await fetch(`${NEXTJS_APP_URL}/api/revalidate/path`, {
+     const response = await fetch(baseUrl.toString(), {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
-         path: `${NEXTJS_APP_URL}/${path}`,
+         path: pathToRevalidate,
          secret: REVALIDATION_SECRET,
        }),
      });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#### Revalidation task
This task takes a `path` as a payload and will revalidate the path you specify, using the handler you set up previously.
<Note>
To run this task locally you will need to set the `REVALIDATION_SECRET` environment variable in your `.env.local` file (or `.env` file if using Pages router).
To run this task in production, you will need to set the `REVALIDATION_SECRET` environment variable in Vercel, in your project settings, and also in your environment variables in the Trigger.dev dashboard.
</Note>
```ts trigger/revalidate-path.ts
import { logger, task } from "@trigger.dev/sdk/v3";
const NEXTJS_APP_URL = process.env.NEXTJS_APP_URL; // e.g. "http://localhost:3000" or "https://my-nextjs-app.vercel.app"
const REVALIDATION_SECRET = process.env.REVALIDATION_SECRET; // Create a REVALIDATION_SECRET and set it in your environment variables
export const revalidatePath = task({
id: "revalidate-path",
run: async (payload: { path: string }) => {
const { path } = payload;
try {
const response = await fetch(`${NEXTJS_APP_URL}/api/revalidate/path`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
path: `${NEXTJS_APP_URL}/${path}`,
secret: REVALIDATION_SECRET,
}),
});
if (response.ok) {
logger.log("Path revalidation successful", { path });
return { success: true };
} else {
logger.error("Path revalidation failed", {
path,
statusCode: response.status,
statusText: response.statusText,
});
return {
success: false,
error: `Revalidation failed with status ${response.status}: ${response.statusText}`,
};
}
} catch (error) {
logger.error("Path revalidation encountered an error", {
path,
error: error instanceof Error ? error.message : String(error),
});
return {
success: false,
error: `Failed to revalidate path due to an unexpected error`,
};
}
},
});
```
#### Revalidation task
This task takes a `path` as a payload and will revalidate the path you specify, using the handler you set up previously.
<Note>
To run this task locally you will need to set the `REVALIDATION_SECRET` environment variable in your `.env.local` file (or `.env` file if using Pages router).
To run this task in production, you will need to set the `REVALIDATION_SECRET` environment variable in Vercel, in your project settings, and also in your environment variables in the Trigger.dev dashboard.
</Note>
```ts trigger/revalidate-path.ts
import { logger, task } from "@trigger.dev/sdk/v3";
const NEXTJS_APP_URL = process.env.NEXTJS_APP_URL; // e.g. "http://localhost:3000" or "https://my-nextjs-app.vercel.app"
const REVALIDATION_SECRET = process.env.REVALIDATION_SECRET; // Create a REVALIDATION_SECRET and set it in your environment variables
// Validate environment variables at startup
if (!NEXTJS_APP_URL) {
throw new Error("NEXTJS_APP_URL environment variable is required");
}
if (!REVALIDATION_SECRET) {
throw new Error("REVALIDATION_SECRET environment variable is required");
}
export const revalidatePath = task({
id: "revalidate-path",
run: async (payload: { path: string }) => {
const { path } = payload;
// Ensure clean URL construction
const baseUrl = new URL("/api/revalidate/path", NEXTJS_APP_URL);
const pathToRevalidate = new URL(path, NEXTJS_APP_URL).pathname;
try {
const response = await fetch(baseUrl.toString(), {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
path: pathToRevalidate,
secret: REVALIDATION_SECRET,
}),
});
if (response.ok) {
logger.log("Path revalidation successful", { path });
return { success: true };
} else {
logger.error("Path revalidation failed", {
path,
statusCode: response.status,
statusText: response.statusText,
});
return {
success: false,
error: `Revalidation failed with status ${response.status}: ${response.statusText}`,
};
}
} catch (error) {
logger.error("Path revalidation encountered an error", {
path,
error: error instanceof Error ? error.message : String(error),
});
return {
success: false,
error: `Failed to revalidate path due to an unexpected error`,
};
}
},
});
```

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (3)
docs/guides/frameworks/nextjs.mdx (3)

267-293: Consider adding JSDoc documentation for the route handler.

While the implementation is solid, adding JSDoc documentation would improve maintainability and help other developers understand the API's purpose and requirements.

Add this documentation above the route handler:

/**
 * Route handler for revalidating Next.js paths
 * @route POST /api/revalidate/path
 * @param {Object} request - The request object containing path and secret
 * @returns {Object} JSON response indicating revalidation status
 */

297-326: Consider adding JSDoc documentation for the API route handler.

While the implementation is solid, adding JSDoc documentation would improve maintainability and help other developers understand the API's purpose and requirements.

Add this documentation above the route handler:

/**
 * API route handler for revalidating Next.js paths
 * @route POST /api/revalidate/path
 * @param {NextApiRequest} req - The request object containing path and secret
 * @param {NextApiResponse} res - The response object
 * @returns {Promise<void>}
 */

395-399: Improve JSON payload example.

The current JSON example contains a comment which is not valid JSON syntax. Consider providing multiple complete, valid examples.

Replace the current example with:

{
  "path": "blog"
}

And add more examples:

{
  "path": "posts/123"
}
{
  "path": "categories/tech"
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 628389d and df5cd7e.

📒 Files selected for processing (1)
  • docs/guides/frameworks/nextjs.mdx (1 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/guides/frameworks/nextjs.mdx

[uncategorized] ~334-~334: Possible missing comma found.
Context: ...p previously. To run this task locally you will need to set the `REVALIDATION_...

(AI_HYDRA_LEO_MISSING_COMMA)

Comment on lines +346 to +389
export const revalidatePath = task({
id: "revalidate-path",
run: async (payload: { path: string }) => {
const { path } = payload;

try {
const response = await fetch(`${NEXTJS_APP_URL}/api/revalidate/path`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
path: `${NEXTJS_APP_URL}/${path}`,
secret: REVALIDATION_SECRET,
}),
});

if (response.ok) {
logger.log("Path revalidation successful", { path });
return { success: true };
} else {
logger.error("Path revalidation failed", {
path,
statusCode: response.status,
statusText: response.statusText,
});
return {
success: false,
error: `Revalidation failed with status ${response.status}: ${response.statusText}`,
};
}
} catch (error) {
logger.error("Path revalidation encountered an error", {
path,
error: error instanceof Error ? error.message : String(error),
});
return {
success: false,
error: `Failed to revalidate path due to an unexpected error`,
};
}
},
});
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance type safety and input validation.

Consider adding input validation and improving type safety:

  1. Define a proper type for the payload
  2. Add validation for the path format

Apply these improvements:

+type RevalidatePathPayload = {
+  path: string;
+};
+
+function isValidPath(path: string): boolean {
+  return path.length > 0 && !path.includes('..') && !path.startsWith('/');
+}
+
 export const revalidatePath = task({
   id: "revalidate-path",
-  run: async (payload: { path: string }) => {
+  run: async (payload: RevalidatePathPayload) => {
     const { path } = payload;
+
+    if (!isValidPath(path)) {
+      logger.error("Invalid path format", { path });
+      return {
+        success: false,
+        error: "Invalid path format. Path should not be empty, contain '..' or start with '/'",
+      };
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const revalidatePath = task({
id: "revalidate-path",
run: async (payload: { path: string }) => {
const { path } = payload;
try {
const response = await fetch(`${NEXTJS_APP_URL}/api/revalidate/path`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
path: `${NEXTJS_APP_URL}/${path}`,
secret: REVALIDATION_SECRET,
}),
});
if (response.ok) {
logger.log("Path revalidation successful", { path });
return { success: true };
} else {
logger.error("Path revalidation failed", {
path,
statusCode: response.status,
statusText: response.statusText,
});
return {
success: false,
error: `Revalidation failed with status ${response.status}: ${response.statusText}`,
};
}
} catch (error) {
logger.error("Path revalidation encountered an error", {
path,
error: error instanceof Error ? error.message : String(error),
});
return {
success: false,
error: `Failed to revalidate path due to an unexpected error`,
};
}
},
});
```
type RevalidatePathPayload = {
path: string;
};
function isValidPath(path: string): boolean {
return path.length > 0 && !path.includes('..') && !path.startsWith('/');
}
export const revalidatePath = task({
id: "revalidate-path",
run: async (payload: RevalidatePathPayload) => {
const { path } = payload;
if (!isValidPath(path)) {
logger.error("Invalid path format", { path });
return {
success: false,
error: "Invalid path format. Path should not be empty, contain '..' or start with '/'",
};
}
try {
const response = await fetch(`${NEXTJS_APP_URL}/api/revalidate/path`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
path: `${NEXTJS_APP_URL}/${path}`,
secret: REVALIDATION_SECRET,
}),
});
if (response.ok) {
logger.log("Path revalidation successful", { path });
return { success: true };
} else {
logger.error("Path revalidation failed", {
path,
statusCode: response.status,
statusText: response.statusText,
});
return {
success: false,
error: `Revalidation failed with status ${response.status}: ${response.statusText}`,
};
}
} catch (error) {
logger.error("Path revalidation encountered an error", {
path,
error: error instanceof Error ? error.message : String(error),
});
return {
success: false,
error: `Failed to revalidate path due to an unexpected error`,
};
}
},
});

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (1)
docs/guides/frameworks/nextjs.mdx (1)

395-399: Enhance the JSON payload example with better formatting and documentation.

The JSON example could be more helpful with proper formatting and additional examples.

Replace the current JSON with:

-{
-  "path": "<path-to-revalidate>" // e.g. "blog"
-}
+{
+  // The path to revalidate, relative to your site's root
+  "path": "blog/post-1",  // Will revalidate /blog/post-1
+  
+  // Optional: specify the type of revalidation (App Router only)
+  "type": "page"  // Can be "page" or "layout"
+}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between df5cd7e and d025e2f.

📒 Files selected for processing (1)
  • docs/guides/frameworks/nextjs.mdx (1 hunks)

Comment on lines +299 to +326
```ts pages/api/revalidate/path.ts
import type { NextApiRequest, NextApiResponse } from "next";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
if (req.method !== "POST") {
return res.status(405).json({ message: "Method not allowed" });
}

const { path, secret } = req.body;

if (secret !== process.env.REVALIDATION_SECRET) {
return res.status(401).json({ message: "Invalid secret" });
}

if (!path) {
return res.status(400).json({ message: "Path is required" });
}

await res.revalidate(path);

return res.json({ revalidated: true });
} catch (err) {
console.error("Error revalidating path:", err);
return res.status(500).json({ message: "Error revalidating path" });
}
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance type safety and error handling in the Pages Router handler.

Consider these improvements to align with best practices:

  1. Add type restriction for HTTP methods
  2. Add proper type definitions for the request body
  3. Enhance error handling with specific error types

Apply these improvements:

+type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
+interface RevalidateRequest extends NextApiRequest {
+  method: HttpMethod;
+  body: {
+    path: string;
+    secret: string;
+  };
+}

-export default async function handler(req: NextApiRequest, res: NextApiResponse) {
+export default async function handler(req: RevalidateRequest, res: NextApiResponse) {
   try {
     if (req.method !== "POST") {
       return res.status(405).json({ message: "Method not allowed" });
     }

     const { path, secret } = req.body;

     if (secret !== process.env.REVALIDATION_SECRET) {
       return res.status(401).json({ message: "Invalid secret" });
     }

     if (!path) {
       return res.status(400).json({ message: "Path is required" });
     }

     await res.revalidate(path);

     return res.json({ revalidated: true });
   } catch (err) {
-    console.error("Error revalidating path:", err);
+    console.error(`Error revalidating path: ${err instanceof Error ? err.message : String(err)}`);
     return res.status(500).json({ message: "Error revalidating path" });
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```ts pages/api/revalidate/path.ts
import type { NextApiRequest, NextApiResponse } from "next";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
if (req.method !== "POST") {
return res.status(405).json({ message: "Method not allowed" });
}
const { path, secret } = req.body;
if (secret !== process.env.REVALIDATION_SECRET) {
return res.status(401).json({ message: "Invalid secret" });
}
if (!path) {
return res.status(400).json({ message: "Path is required" });
}
await res.revalidate(path);
return res.json({ revalidated: true });
} catch (err) {
console.error("Error revalidating path:", err);
return res.status(500).json({ message: "Error revalidating path" });
}
}
```
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
interface RevalidateRequest extends NextApiRequest {
method: HttpMethod;
body: {
path: string;
secret: string;
};
}
export default async function handler(req: RevalidateRequest, res: NextApiResponse) {
try {
if (req.method !== "POST") {
return res.status(405).json({ message: "Method not allowed" });
}
const { path, secret } = req.body;
if (secret !== process.env.REVALIDATION_SECRET) {
return res.status(401).json({ message: "Invalid secret" });
}
if (!path) {
return res.status(400).json({ message: "Path is required" });
}
await res.revalidate(path);
return res.json({ revalidated: true });
} catch (err) {
console.error(`Error revalidating path: ${err instanceof Error ? err.message : String(err)}`);
return res.status(500).json({ message: "Error revalidating path" });
}
}

Comment on lines +269 to +293
```ts app/api/revalidate/path/route.ts
import { NextRequest, NextResponse } from "next/server";
import { revalidatePath } from "next/cache";

export async function POST(request: NextRequest) {
try {
const { path, type, secret } = await request.json();
// Create a REVALIDATION_SECRET and set it in your environment variables
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ message: "Invalid secret" }, { status: 401 });
}

if (!path) {
return NextResponse.json({ message: "Path is required" }, { status: 400 });
}

revalidatePath(path, type);

return NextResponse.json({ revalidated: true });
} catch (err) {
console.error("Error revalidating path:", err);
return NextResponse.json({ message: "Error revalidating path" }, { status: 500 });
}
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance type safety and error handling in the App Router handler.

Consider these improvements to align with best practices:

  1. Add proper type definitions for the request body
  2. Enhance error handling with specific error types
  3. Document the optional type parameter

Apply these improvements:

+type RevalidateRequestBody = {
+  path: string;
+  type?: "page" | "layout";  // Optional parameter to specify revalidation type
+  secret: string;
+};

 export async function POST(request: NextRequest) {
   try {
-    const { path, type, secret } = await request.json();
+    const body = await request.json() as RevalidateRequestBody;
+    const { path, type, secret } = body;

     if (secret !== process.env.REVALIDATION_SECRET) {
       return NextResponse.json({ message: "Invalid secret" }, { status: 401 });
     }

     if (!path) {
       return NextResponse.json({ message: "Path is required" }, { status: 400 });
     }

     revalidatePath(path, type);

     return NextResponse.json({ revalidated: true });
   } catch (err) {
-    console.error("Error revalidating path:", err);
+    console.error(`Error revalidating path: ${err instanceof Error ? err.message : String(err)}`);
     return NextResponse.json({ message: "Error revalidating path" }, { status: 500 });
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```ts app/api/revalidate/path/route.ts
import { NextRequest, NextResponse } from "next/server";
import { revalidatePath } from "next/cache";
export async function POST(request: NextRequest) {
try {
const { path, type, secret } = await request.json();
// Create a REVALIDATION_SECRET and set it in your environment variables
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ message: "Invalid secret" }, { status: 401 });
}
if (!path) {
return NextResponse.json({ message: "Path is required" }, { status: 400 });
}
revalidatePath(path, type);
return NextResponse.json({ revalidated: true });
} catch (err) {
console.error("Error revalidating path:", err);
return NextResponse.json({ message: "Error revalidating path" }, { status: 500 });
}
}
```
```ts app/api/revalidate/path/route.ts
import { NextRequest, NextResponse } from "next/server";
import { revalidatePath } from "next/cache";
type RevalidateRequestBody = {
path: string;
type?: "page" | "layout"; // Optional parameter to specify revalidation type
secret: string;
};
export async function POST(request: NextRequest) {
try {
const body = await request.json() as RevalidateRequestBody;
const { path, type, secret } = body;
if (secret !== process.env.REVALIDATION_SECRET) {
return NextResponse.json({ message: "Invalid secret" }, { status: 401 });
}
if (!path) {
return NextResponse.json({ message: "Path is required" }, { status: 400 });
}
revalidatePath(path, type);
return NextResponse.json({ revalidated: true });
} catch (err) {
console.error(`Error revalidating path: ${err instanceof Error ? err.message : String(err)}`);
return NextResponse.json({ message: "Error revalidating path" }, { status: 500 });
}
}
```

@ericallam ericallam merged commit e92459b into main Nov 1, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants