Skip to content

Redirections ​

301 redirects and the 404 monitor; imports the rules of Redirection and Yoast SEO Premium.

kitloom/redirects · admins: kitloom/redirects-filament, kitloom/redirects-nova

Video lessons ​

Recorded in the Filament admin; the Nova admin works the same way.

404 Monitor
Redirects
Redirect settings

Rank Math's Redirections and 404 Monitor, on its own tables and settings: a site moved from WordPress keeps its rules, its log and how they behave, and Rank Math reads what this package writes.

The admin is kitloom/redirects-filament or kitloom/redirects-nova.

Where things are kept ​

WhatWhere
Rulestable rank_math_redirections
What Rank Math remembered about matchestable rank_math_redirections_cache — a changed rule drops its rows
The 404 logtable rank_math_404_logs
Settingskeys of the option rank-math-options-general

A rule's sources is a serialized list of ['ignore' => ''|'case', 'pattern' => …, 'comparison' => 'exact'|'contains'|'start'|'end'|'regex']. status is active, inactive or trashed; only an active rule works.

php
use Kitloom\Redirects\Rules\Comparison;
use Kitloom\Redirects\Rules\Source;
use Kitloom\Redirects\Rules\Sources;
use Kitloom\WpSchema\WpSchema;

WpSchema::query('redirection')->create([
    'sources' => Sources::encode([new Source('old-page'), new Source('promo/', Comparison::Start)]),
    'url_to' => '/new-page/',
    'header_code' => 301,
    'status' => 'active',
]);

How rules work ​

  • Before anything else answers, for every path but the ones in kitloom-redirects.ignore_prefixes (the admin).
  • Exact patterns are paths without slashes at either end; ignore: case compares without case; a pattern with ? compares the query string too.
  • A regex rule puts its groups into the destination: ^shop/(.+)$ → /store/$1/. What a group captures can never change the site the rule leads to: a destination written as a path stays a path on this site, one written as https://other.example/$1 keeps that host — a path that would leave it (/go//evil.example for ^go/(.*)$ → $1) is passed over as if the rule had not matched.
  • 301, 302 and 307 redirect; 410 and 451 answer with that status and the site's not-found page.
  • When several rules match, the newest wins. A hit counts in hits and last_accessed.

Coming from Redirection ​

Import from Redirection

A site that ran the Redirection plugin (John Godley) keeps its rules after the move by taking them over once: Redirects → Settings → Import from Redirection (the button is there while Redirection's tables hold rules; in Nova, a switch on the same page that imports after the save), or from the console:

bash
php artisan redirects:import --dry-run   # what would come over, what would not, and why
php artisan redirects:import             # take them

Each rule becomes a rule here with its hits and last visit; a switched-off rule stays off. Redirection's own tables are only read, and running the import again adds nothing: a rule already here with the same target is passed over, even one switched off or trashed since, and an address with an active rule of its own here keeps it. What changed on the way and what stayed behind is listed with the reason — read it before the site goes live.

How the rules change:

  • Regular expressions: Redirection compared them with the whole address, leading slash and query string included; here they see the path, so ^/blog/(.*)$ becomes ^blog/(.*)$, and \1 or ${1} in the target become $1. A pattern not anchored with ^/ or $ kept the rest of the address around the match in Redirection; here the target is all there is. A group no longer captures the trailing slash or the query string.
  • A source without a query string matches whatever query the visitor sends, and the trailing slash never counts — in Redirection both could be asked for. "Ignore" and "pass" for a source with a query string compare it whole here; "pass" no longer hands the visitor's parameters to the target.
  • 308 becomes 301 and 303 becomes 302; 410 and 451 close the address as before.
  • A rule for "only when the page is not found" or for the site's own host becomes a plain rule. [lower], [upper], [dashes], [underscores] in a target are dropped, the text inside stays.
  • The order is kept: the rule Redirection ran first still wins.
  • A rule switched on inside a switched-off group stays on: Redirection asked only the rule, and ran it.

What stays behind: rules that ask more than the address (signed in, role, referrer, browser, cookie, header, IP, language, a custom filter, another host), "random", "pass-through" and "do nothing" rules — the rules after a "do nothing" one now catch its addresses — other codes than those above, a regex that reads the query string, a rule for the site's root, and targets made anew for each visit ([userid], [unixtime], [md5], a post ID). The rules of Redirection's Apache and Nginx groups come over like the others (WordPress ran them too), but what Redirection wrote into .htaccess or the Nginx config stays on the server until it is taken out. The 404 log and the redirect log are not taken.

Settings ​

KeyWhat
redirections_header_codethe type a new rule starts with
redirections_fallback, redirections_custom_urla missing page: default 404, homepage, or custom — with a 301; JSON pages stay as they are
redirections_post_redirectAuto Post Redirect: a record or a term whose address changes leaves a rule from the old one; rules that led away from the new one are switched off
404_monitor_modesimple: one row per path with a count; advanced: a row per visit with its referer and browser
404_monitor_limithow many rows the log keeps, the newest
404_monitor_ignore_query_parametersthe query string left out of logged paths
404_monitor_excludepaths not logged: exclude and comparison each

A page a rule closed or the fallback sends away is not logged. A visit is written to the log after the page has gone out, so the visitor does not wait for it. The log is cut back to its limit on about one logged visit in fifty, not on every one: for a while it may hold a few dozen rows more than 404_monitor_limit.

Coming from Yoast SEO Premium ​

The redirects of Yoast SEO Premium become rules here, once: while they are in the database, Redirects → Settings → Import from Yoast SEO Premium shows what comes over and takes it (in Nova, a switch on the same page that imports after the save). The same from the console, a dry run first:

bash
php artisan redirects:import --from=yoast --dry-run
php artisan redirects:import --from=yoast
  • Each redirect is a rule of its own, as Premium ran it. A plain one compares the exact path, decoded (%D0%BA… is the word it spells); like Premium, it does not mind the trailing slash, and the case counts.
  • A regular expression stays one, with its $1 in the destination, and the case counts as in Premium. Premium matched it against the address with its leading slash and query string; here it sees the path: ^/blog/(.*) becomes ^blog/(.*), a / at the start without ^ matches at the start or after a slash, and a closing /$ becomes $. An expression that reads the query string (\?) is left out.
  • A destination on the site gets its leading slash, and the trailing one when the permalinks end with a slash, as Premium sent it (new-page → /new-page/) — not with a query, a fragment or a dot in its path (docs/guide.pdf), nor the home page. 410 and 451 send nowhere.
  • Premium asks its plain redirects before the expressions; here the newest rule wins, so the expressions are made first.
  • A source that has a rule here already keeps it; running the import again makes nothing new. Premium's own options stay as they are.
  • Left out, and named with why: a redirect without a source or a destination, one for the site's root, a type no rule takes, an expression that does not work or reads the query string.

They are read where Premium keeps them — the option wpseo-premium-redirects-base (origin, url, type, format), before Premium 3.1 wpseo-premium-redirects and wpseo-premium-redirects-regex — and taken as Premium's own redirect handler, and the Redirection and Rank Math importers of the same option, read them. One difference stays: a plain redirect here also catches its address with a query string, which Premium's did not.

AI agents ​

With kitloom/ai installed, an agent whose user has manage_redirections lists, creates and changes rules (redirects_list, redirects_create, redirects_update) and moves them to the trash (redirects_trash — never deletes); with manage_404_log it reads the 404 log (not_found_list) and turns rows of it into one rule (redirect_from_404). With manage_redirections it also reads and changes the settings page (redirects_settings_get, redirects_settings_update): the code a new rule starts with, where a missing page goes, the redirect a changed slug leaves, and how the 404 log keeps its rows — only what it sends changes, and the rest of Rank Math's general option stays. Sources are a list of {path, comparison, ignore_case}, the destination is to, the code code. kitloom-redirects.ai.register false — no redirect tools.

Configuration ​

config/kitloom-redirects.php (php artisan vendor:publish --tag=kitloom-redirects-config): paths never redirected, the 404 log on or off, the rule cache.

kitloom — modules and themes for Laravel.
Pricing · Services · License · Refunds · Privacy · Community · [email protected]