Skip to main content

Redirects Manager

Magento ships a basic URL rewrite admin and that's it — no metadata, no CSV import, no audit of who created what when, no log of which redirects are actually being hit. The Redirects Manager fixes all of those without replacing Magento's underlying url_rewrite table.

How it works

A sidecar table byte8_seosuite_redirect (FK with CASCADE to url_rewrite) holds the metadata Magento core doesn't:

  • sourcemanual / imported / auto_healed / oos_engine
  • created_by — admin username at create time
  • batch_id — for grouping CSV imports or programmatic runs
  • notes — free-form per-redirect notes
  • hit_count + last_hit_at — usage stats

The actual 301/302 lives in url_rewrite as before, so nothing about how Magento serves redirects changes. The grid joins both tables for display.

Admin grid

Marketing → SEO Suite → Redirects

Toolbar:

  • New Redirect — single-redirect form
  • Import CSV — bulk import with dry-run

Mass actions:

  • Export selected to CSV — same columns as the import format, downloadable
  • Delete — removes both the sidecar row AND the underlying url_rewrite (cascade)

Filters: source, type (301/302), store, created_by, batch_id, dates.

CSV format

Required columns: request_path, target_path. Optional: redirect_type (default 301), store_id (default 0), source (default "imported"), notes.

request_path,target_path,redirect_type,store_id,notes
old-page.html,/new-page.html,301,1,Migrated 2026-04-25
shop/old-cat,shop/new-cat,301,1,
legacy-blog/post,/blog/post,302,0,Temporary while we finalise URL strategy

Header row is required. Column order doesn't matter — the importer maps by name. Unknown columns are ignored.

Use Dry-run to validate the file without writing — same parser, same validation, no DB changes. The success message tells you how many rows would be created vs would fail, and lists the first 20 errors.

CSV export

Mass-select rows in the grid → Export selected to CSV. Or export everything by selecting all then exporting.

Output columns:

request_path, target_path, redirect_type, store_id, source,
created_by, batch_id, notes, hit_count, last_hit_at, created_at

The exported CSV is a valid input to Import — round-trip safe.

Idempotency

RedirectManager::create() is idempotent — re-creating a redirect for a (request_path, store_id) combo that already exists updates the existing rewrite rather than throwing. CSV import takes advantage of this so you can re-run the same import safely.

Programmatic creation

Other features create redirects through the same RedirectManager:

  • 404 log → Create redirect action — sets source to auto_healed, notes the source 404 entry
  • OOS Rules Engine with action=redirect — sets source to oos_engine, notes the threshold trigger
  • CSV importer — sets source to imported, batch_id to import-YYYYMMDD-HHMMSS

So every redirect has provenance — you can always answer "where did this redirect come from?" by glancing at the source column.

Hit tracking

The hit_count and last_hit_at columns are updated by an observer (roadmapped — currently only set when RedirectManager::recordHit() is called explicitly). Useful for finding redirects that haven't been used in 6+ months and can probably be deleted.

Validation

RedirectManager enforces:

  • Request path cannot be empty
  • Redirect type must be 301 or 302
  • Request and target paths cannot be identical
  • Both paths get normalised (leading / stripped, absolute URLs reduced to path component)

Next