Custom Rewrite Rule Removing Query String

Two parts to this answer:

  1. There are multiple things going wrong with your current example, and some of them are caused by WordPress’s rules making things more complicated. If you don’t mind editing your .htaccess file directly, try this. It avoids having to deal with some WordPress magic that isn’t making things easier here. It should do what you want, or be close enough that you can tweak it to do what you want:
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteRule ^f/(.{6-8})$ foo/?bar=$1 [NC,L]
    </IfModule>

You’ll need to remove your plugin code, remove the line that’s in .htaccess (although I guess this should happen automatically), and add this above the WordPress section

Note, this isn’t a redirect. The URL in the browser won’t change, but the URL that PHP sees ‘behind the scenes’ will be the rewritten one.

  1. If you’re interested to try to fix this still using add_rewrite_rule() there are a few things that need fixing. Here’s an updated try, although I can’t easily test this:
    add_rewrite_rule(
            '^f/(.{6-8})$', 
            'index.php?pagename=foo&bar=$matches[1]',
            'top'
        );
  • Don’t escape /
  • Remove leading / on index.php (this is possibly why it got added as a rule in .htaccess instead of running in WordPress itself, which it should have)
  • Remove unneccessary /?
  • Make it specifically 6-8 characters as per your post
  • Simplify the matched character to . (any character). You could make this e.g. [a-zA-Z0-9] if you want to limit to those characters as that’s explicit and clear

The other thing here is are you 100% sure that pagename=foo is the correct way to arrive at this URL. I’m not sure if that’s how index.php works so you’d need to check that.