Skip to main content

CSV format

The same format is used for both import and export. Round-trip safe — what you export, you can re-import.

Required columns

ColumnTypeNotes
request_pathstringPath to redirect FROM. No leading /, no host. E.g. old-page.html, shop/old-cat
target_pathstringPath or absolute URL to redirect TO

Optional columns

ColumnDefaultNotes
redirect_type301Must be 301 or 302
store_id00 = all stores / website-level. Otherwise specific store ID
sourceimportedmanual / imported / auto_healed / oos_engine
notesemptyFree-form

Path normalisation

Both request_path and target_path are normalised by RedirectManager:

  • Leading / stripped (so /old-page.html and old-page.html are equivalent)
  • Absolute URLs (https://example.com/foo) reduced to path component (foo)
  • Whitespace trimmed

So you don't need to be pedantic about leading slashes in your CSV — both forms work.

Validation rules

A row is rejected (logged in the import report, not fatal to the run) if:

  • request_path is empty
  • target_path is empty
  • redirect_type is not 301 or 302
  • request_path equals target_path (would create a loop)

Other validation errors (e.g. malformed paths) bubble up from UrlPersistInterface with their specific message.

Round-trip example

Export from the grid:

request_path,target_path,redirect_type,store_id,source,created_by,batch_id,notes,hit_count,last_hit_at,created_at
old-page.html,/new-page.html,301,1,manual,admin,,Migrated 2026-04-25,42,2026-04-24 18:32:11,2026-04-20 09:15:00
shop/old-cat,shop/new-cat,301,1,imported,admin,import-20260420-091500,,17,2026-04-23 11:08:43,2026-04-20 09:15:00

Re-import the same file → idempotent updates (existing redirects matched by request_path + store_id, sidecar metadata refreshed). Hit_count and last_hit_at columns are present in the export but ignored on import — they're populated by hit-tracking, not by user input.

Recipe — bulk migration from a previous SEO module

If you're migrating off Mageworx / Amasty / a custom redirects module:

  1. Export their data to a CSV with at least request_path and target_path columns
  2. Add a notes column with Migrated from <vendor> on YYYY-MM-DD so you have an audit trail
  3. Add a source column with value imported
  4. Run dry-run first to catch any malformed rows
  5. Run for real with a meaningful batch_id

In the admin grid, filter by batch_id to see all your migrated redirects in one view.

Recipe — recreating from Apache rewrites

Convert .htaccess style:

RewriteRule ^old-page.html$ /new-page.html [R=301,L]
RewriteRule ^shop/old-cat/?$ /shop/new-cat [R=301,L]

To CSV:

request_path,target_path,redirect_type
old-page.html,/new-page.html,301
shop/old-cat,/shop/new-cat,301

Regex-based rules (^/products/([0-9]+)/?$ → /shop/products/$1) are NOT yet supported — roadmapped for v2.10.

Recipe — exporting from one store, importing to another

Export from store A's grid → edit the CSV to change store_id from 1 to 2 (or use 0 for website-level) → import on store B (or the same install). The importer creates new rows scoped to the new store.

Encoding & quoting

Standard CSV: comma-separated, double-quote enclosure when needed (paths with commas would need quoting), \n line endings.

Excel-saved CSVs typically work but watch for BOM characters at the start of the file — those can confuse the header-row parser. Save as "CSV (Comma delimited) (*.csv)" not "CSV UTF-8" if you hit issues.