Skip to content

Create WP-Revalidate Next.js Plugin! #51

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 7 commits into from
May 5, 2025
Merged

Create WP-Revalidate Next.js Plugin! #51

merged 7 commits into from
May 5, 2025

Conversation

brijr
Copy link
Collaborator

@brijr brijr commented May 5, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a WordPress plugin that automatically triggers Next.js cache revalidation when WordPress content changes, supporting posts, pages, categories, tags, authors, media, and custom post types.
    • Added a manual revalidation option and admin notifications for revalidation events.
    • Implemented a secure webhook integration between WordPress and Next.js.
    • Added a new API route in Next.js to handle authenticated revalidation requests.
  • Bug Fixes

    • Improved handling of AJAX actions and URL normalization in the WordPress plugin.
  • Documentation

    • Added detailed setup and troubleshooting guides for the WordPress plugin.
    • Updated main documentation to clarify plugin installation, configuration, and feature set.
  • Chores

    • Updated environment variable examples to include webhook secret configuration.
    • Updated dependency versions.
    • Adjusted file ignore patterns for better project management.
  • Style

    • Reordered import statements for improved code readability.

Copy link

vercel bot commented May 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
next-wp ❌ Failed (Inspect) May 5, 2025 3:58pm

Copy link

coderabbitai bot commented May 5, 2025

Walkthrough

This update introduces a comprehensive integration between a WordPress site and a Next.js application to enable automated and manual cache revalidation. A new WordPress plugin, including documentation and configuration options, is added to send secure webhook requests to a new Next.js API endpoint when WordPress content changes. The Next.js API route authenticates these requests and triggers cache revalidation for relevant content types. Environment variable and documentation updates clarify setup and configuration. Several package dependencies are updated, and minor code organization improvements are made.

Changes

File(s) Change Summary
.env.example Added WORDPRESS_WEBHOOK_SECRET environment variable with instructions for secure key generation.
.gitignore Added CLAUDE.md to ignored files.
README.md Updated revalidation setup instructions, clarified plugin directory, expanded secret configuration guidance, and added a "Plugin Features" section.
app/api/revalidate/route.ts Introduced a new POST API route to handle authenticated webhook requests for cache revalidation, parsing content type and ID, and triggering tag-based cache invalidation.
app/layout.tsx Reordered import statements for improved organization; no functional changes.
package.json Updated dependencies and devDependencies to newer patch/minor versions; no structural or functional changes.
plugin/README.md Added documentation for the new WordPress plugin, including installation, configuration, features, and troubleshooting.
plugin/next-revalidate/README.txt Added plugin metadata, installation/configuration instructions, FAQs, and changelog for the new WordPress plugin.
plugin/next-revalidate/index.php Added an empty PHP file as a directory placeholder for security.
plugin/next-revalidate/next-revalidate.php Added the main WordPress plugin file: registers hooks for content changes, sends authenticated webhooks to Next.js, manages settings and admin notifications, and provides manual revalidation via AJAX.

Sequence Diagram(s)

sequenceDiagram
    participant WP as WordPress Plugin
    participant Admin as WordPress Admin
    participant NextAPI as Next.js /api/revalidate
    participant Cache as Next.js Cache System

    Admin->>WP: Change content (post, page, etc.)
    WP->>NextAPI: POST /api/revalidate (with secret, contentType, contentId)
    NextAPI->>NextAPI: Authenticate secret
    NextAPI->>Cache: revalidateTag(s) based on contentType/contentId
    NextAPI-->>WP: JSON response (success/failure)
    WP-->>Admin: (Optional) Admin notification
Loading

Poem

🐇
A secret handshake, WordPress and Next,
Now talk in whispers, cache to protect.
With webhooks sent and tags re-spun,
Revalidation’s swiftly done!
Plugins and routes, all in sync,
A rabbit’s wink—faster than you think!
🥕


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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

@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

🧹 Nitpick comments (12)
app/api/revalidate/route.ts (2)

28-62: Consider refactoring content type handling for better maintainability

The current implementation uses a long if-else chain for determining content types and building tags. This could be refactored to be more maintainable and DRY.

- // Determine which tags to revalidate
- const tagsToRevalidate = ["wordpress"];
-
- // Add content type specific tag
- if (contentType === "post") {
-   tagsToRevalidate.push("posts");
-   if (contentId) {
-     tagsToRevalidate.push(`post-${contentId}`);
-   }
- } else if (contentType === "page") {
-   tagsToRevalidate.push("pages");
-   if (contentId) {
-     tagsToRevalidate.push(`page-${contentId}`);
-   }
- } else if (contentType === "category") {
-   tagsToRevalidate.push("categories");
-   if (contentId) {
-     tagsToRevalidate.push(`category-${contentId}`);
-   }
- } else if (contentType === "tag") {
-   tagsToRevalidate.push("tags");
-   if (contentId) {
-     tagsToRevalidate.push(`tag-${contentId}`);
-   }
- } else if (contentType === "author" || contentType === "user") {
-   tagsToRevalidate.push("authors");
-   if (contentId) {
-     tagsToRevalidate.push(`author-${contentId}`);
-   }
- } else if (contentType === "media") {
-   tagsToRevalidate.push("media");
-   if (contentId) {
-     tagsToRevalidate.push(`media-${contentId}`);
-   }
- }
+ // Determine which tags to revalidate
+ const tagsToRevalidate = ["wordpress"];
+ 
+ // Mapping of content types to tag names
+ const contentTypeMap = {
+   post: "posts",
+   page: "pages",
+   category: "categories",
+   tag: "tags",
+   author: "authors",
+   user: "authors",
+   media: "media",
+ };
+ 
+ // Add content type specific tag
+ const tagName = contentTypeMap[contentType];
+ if (tagName) {
+   tagsToRevalidate.push(tagName);
+   
+   // For authors, we need to handle both 'author' and 'user' content types
+   const idPrefix = contentType === "user" ? "author" : contentType;
+   
+   if (contentId) {
+     tagsToRevalidate.push(`${idPrefix}-${contentId}`);
+   }
+ }

1-81: Consider adding rate limiting to prevent abuse

The webhook endpoint doesn't implement any rate limiting, which could lead to potential DoS vulnerability if excessive revalidation requests are sent.

You might want to add a simple rate limiting mechanism or integrate with a rate limiting middleware if available in your framework.

plugin/README.md (3)

3-3: Minor grammatical improvement suggested

-This plugin enables automatic revalidation of your Next.js site when content is changed in WordPress.
+This plugin enables automatic revalidation of your Next.js site when content is changed on WordPress.
🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ...ur Next.js site when content is changed in WordPress. ## Installation 1. Upload the `next-...

(IN_FACEBOOK)


34-34: Minor grammatical improvement suggested

-1. When content in WordPress is created, updated, or deleted, the plugin sends a webhook to your Next.js API route
+1. When content on WordPress is created, updated, or deleted, the plugin sends a webhook to your Next.js API route
🧰 Tools
🪛 LanguageTool

[grammar] ~34-~34: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ..." ``` ## How It Works 1. When content in WordPress is created, updated, or deleted, the pl...

(IN_FACEBOOK)


1-54: Consider adding documentation about customizing the API endpoint path

The README assumes a fixed API endpoint path, but users might want to customize it.

Consider adding a section about how to customize the API endpoint path if your implementation supports it.

🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ...ur Next.js site when content is changed in WordPress. ## Installation 1. Upload the `next-...

(IN_FACEBOOK)


[grammar] ~34-~34: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ..." ``` ## How It Works 1. When content in WordPress is created, updated, or deleted, the pl...

(IN_FACEBOOK)

plugin/next-revalidate/README.txt (2)

15-15: Minor grammatical improvement suggested

-Next.js Revalidation is a WordPress plugin designed to work with the `next-wp` Next.js starter template. It triggers revalidation of your Next.js site's cache whenever content is added, updated, or deleted in WordPress.
+Next.js Revalidation is a WordPress plugin designed to work with the `next-wp` Next.js starter template. It triggers revalidation of your Next.js site's cache whenever content is added, updated, or deleted on WordPress.
🧰 Tools
🪛 LanguageTool

[grammar] ~15-~15: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ...r content is added, updated, or deleted in WordPress. The plugin sends webhooks to your Nex...

(IN_FACEBOOK)


13-17: Consider adding a link to the next-wp starter template

The README mentions a next-wp starter template but doesn't provide a link to it.

Add a link to the next-wp starter template to help users find it easily.

🧰 Tools
🪛 LanguageTool

[grammar] ~15-~15: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ...r content is added, updated, or deleted in WordPress. The plugin sends webhooks to your Nex...

(IN_FACEBOOK)

plugin/next-revalidate/next-revalidate.php (5)

131-134: Missing value attribute prevents reliable checkbox handling

HTML checkboxes should carry an explicit value attribute (usually "1").
Without it, browsers default to "on", which is inconsistent with the integer stored in the DB after applying the previous fix and forces extra casting later on.

-echo '<input type="checkbox" id="enable_notifications" name="' . $this->option_name . '[enable_notifications]" ' . checked($value, true, false) . ' />';
+echo '<input type="checkbox" id="enable_notifications" name="' . $this->option_name . '[enable_notifications]" value="1" ' . checked($value, 1, false) . ' />';

248-252: No revalidation when a post is moved to the trash

deleted_post only fires after the item is permanently removed.
For most editors the first destructive action is “Move to Trash”, which triggers trashed_post.
Consider hooking that action as well so cached pages disappear immediately when authors trash a post.

add_action( 'trashed_post', array( $this, 'on_post_delete' ), 10 );

288-313: Duplicated taxonomy mapping – streamline the switch

on_term_change() already converts post_tagtag and categorycategory.
The extra cases inside the switch therefore never execute.
Removing them makes the intent clearer:

-            case 'post_tag':
-                $contentType = 'tag';
-                break;

324-336: Timeout of 5 s might be too aggressive for remote builds

Large Next.js deployments (or cold-start serverless functions) can legitimately take > 5 s to answer.
A premature timeout will surface as a false negative to editors.

If latency is a concern, bump the limit (e.g. 15 s) or make it configurable through the settings page.

-            'timeout' => 5,
+            'timeout' => 15,

330-335: Send secret via Authorization header instead of custom header

Using a standard Authorization: Bearer <token> header improves interoperability with frameworks and middleware that automatically process auth headers and can be inspected more easily by hosting platforms.

-                'Content-Type' => 'application/json',
-                'x-webhook-secret' => $this->options['webhook_secret']
+                'Content-Type'  => 'application/json',
+                'Authorization' => 'Bearer ' . $this->options['webhook_secret']
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dd8092e and 865f1e4.

⛔ Files ignored due to path filters (2)
  • plugin/next-revalidate.zip is excluded by !**/*.zip
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • .env.example (1 hunks)
  • .gitignore (1 hunks)
  • README.md (2 hunks)
  • app/api/revalidate/route.ts (1 hunks)
  • app/layout.tsx (1 hunks)
  • package.json (1 hunks)
  • plugin/README.md (1 hunks)
  • plugin/next-revalidate/README.txt (1 hunks)
  • plugin/next-revalidate/index.php (1 hunks)
  • plugin/next-revalidate/next-revalidate.php (1 hunks)
🧰 Additional context used
🪛 LanguageTool
plugin/README.md

[grammar] ~3-~3: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ...ur Next.js site when content is changed in WordPress. ## Installation 1. Upload the `next-...

(IN_FACEBOOK)


[grammar] ~34-~34: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ..." ``` ## How It Works 1. When content in WordPress is created, updated, or deleted, the pl...

(IN_FACEBOOK)

plugin/next-revalidate/README.txt

[grammar] ~15-~15: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ...r content is added, updated, or deleted in WordPress. The plugin sends webhooks to your Nex...

(IN_FACEBOOK)

🔇 Additional comments (30)
.gitignore (1)

37-38: Add CLAUDE.md to .gitignore
Including CLAUDE.md prevents accidental commits of local or sensitive documentation notes.

plugin/next-revalidate/index.php (1)

1-2: Add index.php for security stub
The placeholder file will prevent directory listing within the plugin directory as per WordPress best practices.

.env.example (1)

3-6: Document WORDPRESS_WEBHOOK_SECRET usage
Good addition of guidance for generating a secure webhook secret without exposing real keys.

app/layout.tsx (1)

3-14: Reordered imports for clarity
The import statements have been logically grouped and reorganized without affecting functionality.

README.md (3)

436-438: Clarify plugin installation path
Updating instructions to use the /plugin directory and offering zip options aligns with the actual file structure.


444-444: Align env var instructions with .env.example
Ensuring users add WORDPRESS_WEBHOOK_SECRET to their environment matches the plugin requirements.


454-463: Add detailed Plugin Features section
The new feature list clearly communicates the capabilities of the WordPress revalidation plugin.

package.json (4)

13-20: Radix UI packages version update looks good!

All Radix UI packages have been consistently updated to their latest compatible versions.


25-25: Next.js version update supports new revalidation API

The update from 15.2.3 to 15.3.1 aligns with the new revalidation functionality being added.


27-27: Other dependency updates are consistent

The updates to query-string, react-hook-form, and zod look good and maintain project compatibility.

Also applies to: 30-30, 35-35


39-41: TypeScript and dev dependencies updated consistently

All TypeScript-related dependencies and ESLint configurations have been properly updated to maintain compatibility.

Also applies to: 43-44, 47-47

app/api/revalidate/route.ts (5)

1-3: Imports look good

The necessary imports for Next.js cache revalidation and request/response handling are properly included.


4-16: Webhook security implementation is robust

Good implementation of webhook secret validation before processing the request. The error response appropriately returns a 401 status code without leaking sensitive information.


18-26: Request validation is implemented correctly

The code properly extracts and validates the required fields from the request body.


64-73: Revalidation loop and response handling look good

The implementation for revalidating all determined tags and returning the response is well-structured.


74-80: Error handling is robust

Good implementation of error handling with appropriate logging and error response.

plugin/README.md (7)

1-2: Clear title and purpose

The README title is descriptive and clearly indicates the plugin's purpose.


5-11: Installation instructions are clear and comprehensive

The instructions provide multiple installation methods and proper steps for activation and configuration.


12-22: Configuration section is well-structured

The configuration steps for the WordPress plugin settings are clear and provide good security advice for generating a webhook secret.


23-30: Next.js environment setup is clearly explained

The instructions for setting up the environment variables in Next.js are concise and match the implementation in the API route.


32-38: How It Works section is informative

The explanation of the plugin's functionality is clear and accurately describes the interaction between WordPress and Next.js.

🧰 Tools
🪛 LanguageTool

[grammar] ~34-~34: The usual collocation for “WordPress” is “on”. Did you mean “on WordPress”?
Context: ..." ``` ## How It Works 1. When content in WordPress is created, updated, or deleted, the pl...

(IN_FACEBOOK)


39-45: Features section is comprehensive

The features list provides a good overview of what the plugin offers.


46-53: Troubleshooting section is helpful

The troubleshooting tips address common issues users might face.

plugin/next-revalidate/README.txt (7)

1-10: Plugin metadata is complete and follows WordPress standards

The metadata section includes all required information for a WordPress plugin and follows the standard format.


11-11: Clear plugin description

The one-line description is concise and clearly communicates the plugin's purpose.


19-26: Features section is comprehensive

The key features list provides a good overview of the plugin's capabilities.


52-54: Custom post type support is documented

Good to see explicit mention of custom post type support, which matches the plugin's capabilities.


56-63: Changelog is clear and follows WordPress standards

The changelog properly documents version changes and fixes.


64-67: Upgrade notice is appropriate

The upgrade notice follows WordPress standards and provides relevant information.


49-50:

✅ Verification successful

Check API endpoint path consistency

The README mentions an API endpoint at /api/revalidate, but the implementation file is at /api/revalidate/route.ts. Make sure this path discrepancy doesn't cause confusion for users.


🏁 Script executed:

#!/bin/bash
# Verify the actual API endpoint path in the codebase

# Check if the file exists
if [ -f "app/api/revalidate/route.ts" ]; then
  echo "API route exists at app/api/revalidate/route.ts"
  # This is correct according to Next.js App Router conventions
else
  echo "API route not found at expected location"
fi

Length of output: 145


API endpoint path is correct
The app/api/revalidate/route.ts file exists and correctly serves the /api/revalidate endpoint under Next.js App Router conventions. No changes to the README are necessary.

Comment on lines +28 to +62
// Determine which tags to revalidate
const tagsToRevalidate = ["wordpress"];

// Add content type specific tag
if (contentType === "post") {
tagsToRevalidate.push("posts");
if (contentId) {
tagsToRevalidate.push(`post-${contentId}`);
}
} else if (contentType === "page") {
tagsToRevalidate.push("pages");
if (contentId) {
tagsToRevalidate.push(`page-${contentId}`);
}
} else if (contentType === "category") {
tagsToRevalidate.push("categories");
if (contentId) {
tagsToRevalidate.push(`category-${contentId}`);
}
} else if (contentType === "tag") {
tagsToRevalidate.push("tags");
if (contentId) {
tagsToRevalidate.push(`tag-${contentId}`);
}
} else if (contentType === "author" || contentType === "user") {
tagsToRevalidate.push("authors");
if (contentId) {
tagsToRevalidate.push(`author-${contentId}`);
}
} else if (contentType === "media") {
tagsToRevalidate.push("media");
if (contentId) {
tagsToRevalidate.push(`media-${contentId}`);
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add support for custom post types

The current implementation doesn't explicitly handle custom post types which are mentioned in the plugin documentation. Consider adding support for them.

  // Determine which tags to revalidate
  const tagsToRevalidate = ["wordpress"];

  // Add content type specific tag
  if (contentType === "post") {
    tagsToRevalidate.push("posts");
    if (contentId) {
      tagsToRevalidate.push(`post-${contentId}`);
    }
  } else if (contentType === "page") {
    tagsToRevalidate.push("pages");
    if (contentId) {
      tagsToRevalidate.push(`page-${contentId}`);
    }
  } else if (contentType === "category") {
    tagsToRevalidate.push("categories");
    if (contentId) {
      tagsToRevalidate.push(`category-${contentId}`);
    }
  } else if (contentType === "tag") {
    tagsToRevalidate.push("tags");
    if (contentId) {
      tagsToRevalidate.push(`tag-${contentId}`);
    }
  } else if (contentType === "author" || contentType === "user") {
    tagsToRevalidate.push("authors");
    if (contentId) {
      tagsToRevalidate.push(`author-${contentId}`);
    }
  } else if (contentType === "media") {
    tagsToRevalidate.push("media");
    if (contentId) {
      tagsToRevalidate.push(`media-${contentId}`);
    }
+ } else {
+   // Handle custom post types
+   tagsToRevalidate.push(`${contentType}s`);
+   if (contentId) {
+     tagsToRevalidate.push(`${contentType}-${contentId}`);
+   }
  }
📝 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
// Determine which tags to revalidate
const tagsToRevalidate = ["wordpress"];
// Add content type specific tag
if (contentType === "post") {
tagsToRevalidate.push("posts");
if (contentId) {
tagsToRevalidate.push(`post-${contentId}`);
}
} else if (contentType === "page") {
tagsToRevalidate.push("pages");
if (contentId) {
tagsToRevalidate.push(`page-${contentId}`);
}
} else if (contentType === "category") {
tagsToRevalidate.push("categories");
if (contentId) {
tagsToRevalidate.push(`category-${contentId}`);
}
} else if (contentType === "tag") {
tagsToRevalidate.push("tags");
if (contentId) {
tagsToRevalidate.push(`tag-${contentId}`);
}
} else if (contentType === "author" || contentType === "user") {
tagsToRevalidate.push("authors");
if (contentId) {
tagsToRevalidate.push(`author-${contentId}`);
}
} else if (contentType === "media") {
tagsToRevalidate.push("media");
if (contentId) {
tagsToRevalidate.push(`media-${contentId}`);
}
}
// Determine which tags to revalidate
const tagsToRevalidate = ["wordpress"];
// Add content type specific tag
if (contentType === "post") {
tagsToRevalidate.push("posts");
if (contentId) {
tagsToRevalidate.push(`post-${contentId}`);
}
} else if (contentType === "page") {
tagsToRevalidate.push("pages");
if (contentId) {
tagsToRevalidate.push(`page-${contentId}`);
}
} else if (contentType === "category") {
tagsToRevalidate.push("categories");
if (contentId) {
tagsToRevalidate.push(`category-${contentId}`);
}
} else if (contentType === "tag") {
tagsToRevalidate.push("tags");
if (contentId) {
tagsToRevalidate.push(`tag-${contentId}`);
}
} else if (contentType === "author" || contentType === "user") {
tagsToRevalidate.push("authors");
if (contentId) {
tagsToRevalidate.push(`author-${contentId}`);
}
} else if (contentType === "media") {
tagsToRevalidate.push("media");
if (contentId) {
tagsToRevalidate.push(`media-${contentId}`);
}
} else {
// Handle custom post types
tagsToRevalidate.push(`${contentType}s`);
if (contentId) {
tagsToRevalidate.push(`${contentType}-${contentId}`);
}
}

Comment on lines +94 to +112
public function sanitize_settings($input) {
$new_input = array();

if (isset($input['next_url'])) {
// Normalize and sanitize Next.js site URL (remove trailing slash)
$url = rtrim(trim($input['next_url']), '/');
$new_input['next_url'] = esc_url_raw($url);
}

if(isset($input['webhook_secret'])) {
$new_input['webhook_secret'] = sanitize_text_field($input['webhook_secret']);
}

if(isset($input['enable_notifications'])) {
$new_input['enable_notifications'] = (bool)$input['enable_notifications'];
}

return $new_input;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Checkbox can never be switched off – fix enable_notifications sanitisation

enable_notifications is only written when the checkbox is present in the submitted payload, i.e. when it is ticked.
If the user un-ticks the box the field is omitted and the previous value is silently kept, so the option can never be disabled once enabled.

-        if(isset($input['enable_notifications'])) {
-            $new_input['enable_notifications'] = (bool)$input['enable_notifications'];
-        }
+        // Always set a value so the option can be toggled off as well.
+        // Treat any truthy input as enabled, everything else as disabled.
+        $new_input['enable_notifications'] = !empty($input['enable_notifications']) ? 1 : 0;

Copy link

@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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 865f1e4 and 422a153.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • package.json (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
package.json

[error] 48-48: expected , but instead found "typescript"

Remove "typescript"

(parse)


[error] 47-47: The key typescript was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)

🔇 Additional comments (5)
package.json (5)

13-19: Approve Radix UI package version bumps.

The updates to the @radix-ui dependencies look consistent and straightforward. Ensure you test relevant UI components to confirm there are no breaking changes.


25-25: Verify Next.js version compatibility.

You've bumped next to ^15.3.1. Please ensure that any custom Next.js plugin code (e.g., the WP-Revalidate integration) works as expected with this minor upgrade.


27-27: Approve query-string version bump.

The upgrade to ^9.1.2 is fine—no breaking changes are expected.


30-30: Approve react-hook-form version bump.

Moving to ^7.56.2 aligns with your other form-related updates; be sure to run existing form validation tests.


35-35: Approve zod version bump.

Bumping to ^3.24.4 is safe; confirm schema validations still pass.

Comment on lines +39 to +48
"@types/node": "^20.17.32",
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.6",
"@types/react-dom": "^18.3.7",
"autoprefixer": "^10.4.21",
"eslint": "^9.24.0",
"eslint-config-next": "^15.3.0",
"eslint": "^9.26.0",
"eslint-config-next": "^15.3.1",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "^5.8.3"
"typescript": "^5.8.3"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicated typescript entry.

There's a duplicate "typescript": "^5.8.3" key in devDependencies. JSON objects ignore all but the last occurrence, so please remove the redundant entry to avoid confusion.

@@ devDependencies
-    "typescript": "^5.8.3"
📝 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
"@types/node": "^20.17.32",
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.6",
"@types/react-dom": "^18.3.7",
"autoprefixer": "^10.4.21",
"eslint": "^9.24.0",
"eslint-config-next": "^15.3.0",
"eslint": "^9.26.0",
"eslint-config-next": "^15.3.1",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "^5.8.3"
"typescript": "^5.8.3"
"@types/node": "^20.17.32",
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.7",
"autoprefixer": "^10.4.21",
"eslint": "^9.26.0",
"eslint-config-next": "^15.3.1",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"typescript": "^5.8.3"
🧰 Tools
🪛 Biome (1.9.4)

[error] 48-48: expected , but instead found "typescript"

Remove "typescript"

(parse)


[error] 47-47: The key typescript was already declared.

This where a duplicated key was declared again.

If a key is defined multiple times, only the last definition takes effect. Previous definitions are ignored.

(lint/suspicious/noDuplicateObjectKeys)

@brijr brijr merged commit 905d46c into main May 5, 2025
2 of 3 checks passed
@brijr brijr deleted the brijr/plugin branch May 5, 2025 16:01
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.

1 participant