Skip to content
Log in

Match legacy URLs that end in a file extension

On this page

Use this process when you have moved a site to StoreConnect on the same domain and the old site’s URLs end in a file extension, such as /about/team.html. StoreConnect serves the same content at /about/team, so without extension matching every old URL returns a 404.

Extension matching treats the listed extensions as optional. A request for /about/team.html that would otherwise 404 is sent to /about/team, as long as that page exists. It replaces a route mapping for each old URL.

How matching works

  • Off by default. A store with no extensions listed is unaffected.
  • Only after a 404. A page that really exists at /foo.html is served as normal.
  • Route mappings take precedence. If a Route Mapping exists for the requested URL, that mapping applies instead.
  • Content pages and product categories only. The extensionless path must be a visible content page, or a product category whose whole path exists. For example, /womens/shoes.html matches only when the shoes category sits under womens. If neither applies, the 404 stands, so a visitor is never redirected to a missing page. Product pages need no matching or route mapping: /products/<slug>.html already serves the product page directly with a 200, whether or not extension matching is on, and the canonical tag still points at /products/<slug>.
  • Final extension only. /page.html.old does not match html, because the last extension is old.
  • Not case sensitive. .HTML matches html.
  • Query string kept. /about/team.html?ref=email redirects to /about/team?ref=email.

Turn on extension matching

  1. Open the Store record and go to the Store Variables related list.
  2. Create a store variable with the Key routing.matchable_url_extensions and the extensions as the Value, separated by commas. For example, html,htm. A leading dot is ignored, so .html also works.
  3. (Optional) Create a store variable with the Key routing.matchable_url_status to change the response. Leave it unset to redirect with a 301.

    Value Response
    301 (default) Permanent redirect to the extensionless URL. Search engines move the old URL’s ranking to the new one.
    302 Temporary redirect to the extensionless URL.
    200 Serves the page at the old URL with no redirect. The page’s canonical tag still points at the extensionless URL.

    Any other value is treated as 301.

  4. Open an old URL on your storefront, such as https://shop.example.com/about/team.html.

The change applies from the next request. With the default response, the browser lands on https://shop.example.com/about/team and the request returns a 301.

:::note If category URLs on your store follow the category tree (the catalog.category_paths.hierarchical store variable), a match on a single-segment category path redirects twice: first to the extensionless path, then to the full category path. :::

Turn it off

Delete the routing.matchable_url_extensions store variable, or clear the Value. Old URLs with an extension return a 404 again. Search engines and browsers may keep a 301 they have already seen, so use 302 while you are still testing.

Was this article helpful?

Was this article helpful?