Turn on Redirects under WP Visibility → Settings → Modules, then open the new WP Visibility → Redirects page. Under Add a redirect, enter the old path as the Source (/old-page/), the new address as the Target (/new-page/ or a full URL), leave Status at 301, and click Add redirect. Open the old address in a private window to confirm it lands on the new one.
Turn the module on
The module is off by default. Once on, Redirects appears in the WP Visibility menu and the rules table is created. Turning the module off later keeps the rules but stops them firing.
Create a redirect
| Field | What to enter |
|---|---|
| Source | A path on this site starting with /. A full URL on your own domain is accepted and reduced to its path; a URL on another host is refused. The query string is dropped and a trailing slash is ignored, so /old-page and /old-page/ are the same rule. |
| Target | A path like /new-page/, or a full http(s) URL, on this site or another. A bare word such as new-page is refused rather than guessed at. |
| Status | 301 by default. See the table below. |
| Regular expression | Match the source as a pattern instead of an exact path. Patterns are tested against the path, which starts with /, without its trailing slash or query string, and match anywhere in it unless you anchor them with ^ and $. $1, $2 work in the target, but the target replaces only the part of the path the pattern matched, so match the whole path: ^/old/(.*)$ with the target /new/$1/. |
A second rule for the same source is refused: “A redirect for this source already exists.” Edit the existing one instead. The table shows each rule’s hit count, and rules can be searched, edited inline and deleted.
Status codes
| Code | Meaning | Target |
|---|---|---|
| 301 | Moved permanently | Required |
| 302 | Found, temporary | Required |
| 307 | Temporary, keeps the request method | Required |
| 308 | Permanent, keeps the request method | Required |
| 410 | Gone: the page is deliberately removed | None. The old address answers 410 in place |
| 451 | Unavailable for legal reasons | None |
The meanings are the ones defined in RFC 9110 and, for 451, RFC 7725, checked September 27, 2026.
Use 301 for a page that moved. Use 410 for a page that is gone on purpose with no replacement: RFC 9110 defines it as intentionally unavailable and likely permanent, where a 404 does not say whether the absence is temporary or permanent (checked September 27, 2026). Google treats the two the same for indexing and removes a previously indexed URL either way, per its HTTP status code documentation, checked September 27, 2026.
Slug changes are handled for you
While the module is on, changing the slug of a published post, page or public custom post type entry creates a 301 from the old path to the new one, or updates an existing rule for that old path. Two housekeeping steps run at the same time: exact-path rules that pointed at the old path are rewritten to point at the new one, so no chain forms, and any rule whose source is the new path is deleted, so no loop forms. Drafts, revisions, plain ?p=123 permalinks and the front page are not touched.
Loops and chains
- An exact-path rule whose target leads straight back to its own source is refused: “The target redirects straight back to the source.”
- A rule whose target is itself the source of another rule is saved with a warning: visitors will be redirected twice. Point the first rule at the final destination instead. The plugin issues one redirect per request; it does not collapse chains on the fly.
How matching works
Every front-end request is checked before WordPress renders anything. An exact-path rule is one indexed lookup; regular expression rules are tried afterward, in the order they were created, up to 200 of them. Matching is case-sensitive. The visitor’s query string is passed through to the target. Hits are recorded at the end of the request, after the redirect is issued; HEAD requests and 410 or 451 answers are not counted.
A rule whose source matches a page that still exists takes that page over, so write rules only for addresses you have retired.
Import rules from another plugin
Under Import from a CSV on the Redirects page, choose the file, click Preview CSV, read the result, then Import CSV. The preview validates every row and reports how many redirects would be created and how many rows would be skipped, with the problems listed; nothing is written until the import. Three layouts are recognized by their header row:
| Layout | Header | Notes |
|---|---|---|
| WP Visibility | source,target,status,is_regex |
A file with no header is read in this order. status defaults to 301. |
| Redirection plugin export | source,target,regex,code,type,hits,title,status |
Recognized by its code column, which becomes the status. type, hits, title and status are not read, so disabled rules import too. The export has no match type column: rules that match on a referrer, user agent, login, IP and similar conditions are written with the placeholder target /unknown and would import as plain redirects to it, so delete those rows first. A file that does carry a match column has its non-url rows skipped. |
| Rank Math redirections CSV | id,source,matching,destination,type,category,status,ignore |
The Rank Math PRO export. exact and regex rows are read and checked like a rule added by hand, so an exact source must start with / (or be a full URL on this site) and a pattern must allow for the leading /; contains, start and end are skipped with a message; inactive rows are skipped. ignore is not read, so a rule set to ignore case imports as case-sensitive. |
The Redirection header is the one its 5.10.1 CSV exporter writes, and the Rank Math columns are listed in its CSV redirects guide, both checked September 27, 2026.
Each run handles up to 5,000 rows, lists the first 50 problems by row number, and skips duplicates of rules that already exist. Yoast Premium and SEOPress exports are not recognized; reshape them into the WP Visibility source,target,status layout. There is no CSV export.
The same import is available over REST at POST /wp-json/wpvis/v1/redirects/import-csv with the file in a file field; dry_run defaults to true. Rules can also be listed and created at /wp-json/wpvis/v1/redirects, and updated (PUT) or deleted (DELETE) at /wp-json/wpvis/v1/redirects/<id>. All of these need manage_options and do not pass through the review queue.
One page, without the module
The editor sidebar’s Indexing panel has a Redirect (301) to field on every post. It sends that post’s own address to the URL you enter, permanently, and works whether or not the Redirects module is on. It does not create a rule in the table. Use it for a single retired page; use the module for anything else.
Check it
curl -sI https://your-site.com/old-page/ | grep -i "^HTTP\|^location"
Expect a 301 status line (HTTP/2 301 or HTTP/1.1 301, depending on your server) and a location: header with the target. Then check the target itself returns 200, and that the old URL is not also listed in your sitemap (a redirected post that is still published is; trash or noindex it).