Skip to content

Conversation

@szepeviktor
Copy link
Owner

@szepeviktor szepeviktor commented Jan 24, 2026

Adds a filter to mod_rewrite_rules to enforce trailing slashes for URLs without dots.


Summary by cubic

Enforces trailing slashes for paths without dots by injecting an .htaccess rule via the mod_rewrite_rules filter. Requests missing a trailing slash (and with no dot) are 301-redirected to the slash version for canonical URLs and consistent routing.

Written for commit 934401c. Summary will update on new commits.

Adds a filter to mod_rewrite_rules to enforce trailing slashes for URLs without dots.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new MU plugin that enforces trailing slashes on URLs without file extensions by filtering WordPress's mod_rewrite rules. The plugin inserts Apache RewriteRule directives that redirect URLs ending without a slash (and not containing a dot) to their trailing-slash equivalents with a 301 redirect.

Changes:

  • Added new MU plugin _core-auto-trailing-slash.php that filters mod_rewrite_rules to inject rewrite rules for trailing slash enforcement
  • Implements logic to handle both cases where "RewriteEngine On" exists or doesn't exist in the rules
  • Uses priority 20 for the filter to control execution order

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

'mod_rewrite_rules',
static function (string $rules) {
$insertion = <<<HTACCESS
# Add trailing slash if doesn't end with / and doesn't contain a dot

This comment was marked as resolved.

Comment on lines +18 to +21
if (strpos($rules, $needle) === false) {
return $needle.$insertion.$rules;
}
return str_replace($needle, $needle.$insertion, $rules);

This comment was marked as resolved.

Comment on lines +17 to +21
$needle = "RewriteEngine On\n";
if (strpos($rules, $needle) === false) {
return $needle.$insertion.$rules;
}
return str_replace($needle, $needle.$insertion, $rules);
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

There's no check to prevent duplicate insertion of the rewrite rule if this filter is called multiple times or if the rule already exists in the rules string. Consider checking if the insertion content already exists in $rules before adding it again, or storing a flag to track if the insertion has already been performed.

Copilot uses AI. Check for mistakes.
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="mu-plugins/_core-auto-trailing-slash.php">

<violation number="1" location="mu-plugins/_core-auto-trailing-slash.php:14">
P2: Using a 301 redirect here can change non‑GET requests (POST/PUT) to GET and drop the body. That will break API or form submissions sent to no‑dot paths. Prefer a method-preserving redirect (308) or limit the rule to GET/HEAD requests.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

$insertion = <<<HTACCESS
# Add trailing slash if doesn't end with / and doesn't contain a dot
RewriteCond %{REQUEST_URI} !(\.|/$)
RewriteRule ^(.+)$ /$1/ [R=301,L]
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 24, 2026

Choose a reason for hiding this comment

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

P2: Using a 301 redirect here can change non‑GET requests (POST/PUT) to GET and drop the body. That will break API or form submissions sent to no‑dot paths. Prefer a method-preserving redirect (308) or limit the rule to GET/HEAD requests.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At mu-plugins/_core-auto-trailing-slash.php, line 14:

<comment>Using a 301 redirect here can change non‑GET requests (POST/PUT) to GET and drop the body. That will break API or form submissions sent to no‑dot paths. Prefer a method-preserving redirect (308) or limit the rule to GET/HEAD requests.</comment>

<file context>
@@ -0,0 +1,25 @@
+        $insertion = <<<HTACCESS
+# Add trailing slash if doesn't end with / and doesn't contain a dot
+RewriteCond %{REQUEST_URI} !(\.|/$)
+RewriteRule ^(.+)$ /$1/ [R=301,L]
+
+HTACCESS;
</file context>
Fix with Cubic

Update comment to clarify conditions for adding trailing slash.
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