🧰 ToolPicoAll Tools →
HomeBlog › Migrating URLs Without Breaking SEO

Migrating URLs Without Breaking SEO: A Developer's Slug Checklist

Rebuilding a site — new framework, new CMS, new folder structure — almost always means the URLs change too. Here's a practical checklist for converting old titles into new slugs in bulk, without silently colliding with a reserved route or losing search rankings to an unmapped 404.

In this guide

Why you should convert URLs as a batch, not one at a time

Quick answerExport every existing page title or URL into one list first, then run the whole batch through slug generation together — not page by page. Processing everything in one pass is what surfaces duplicate slugs before launch, instead of after a search-engine crawl finds two pages sharing one address.

A migration touches every URL on a site at once, which is a very different problem from cleaning up a single slug when publishing one new post. If you convert titles one at a time as you go, it's easy to miss that "Getting Started" and "Getting Started (2026 Update)" both reduce to a name so similar the site framework treats them as a collision, or that two completely different sections both had a page literally titled "Overview."

Practical scenario: imagine migrating a documentation site with a spreadsheet of 40 old page titles pulled from the CMS export. Pasting that whole list into a bulk slug generator at once — rather than converting titles individually while rebuilding each page — surfaces every duplicate collision up front, with automatic -2, -3 suffixes applied consistently, so the new sitemap can be reviewed as a whole before a single redirect rule is written.

Rule of thumb: if you're touching more than a handful of URLs, treat it as a batch job with one reviewable output list — not a series of one-off manual edits.

Checking new slugs against reserved routes

Quick answerBefore a new slug goes live, check it against your framework's reserved paths — things like admin, api, login, category, tag, or static-asset folders such as assets or static. A page slug that happens to match one of these can shadow a real route or quietly break navigation.

This is a specific, and specifically annoying, migration failure mode: everything works locally, then one content page named exactly admin or feed goes live and starts fighting with a system route for the same path. It's rarely caught in a manual review because the slug itself looks perfectly reasonable — the collision only shows up once both routes exist in the same app.

Worked example (illustrative only): a marketing team migrating a blog wants a page at /api to explain their public API pricing. Checking that candidate slug against a reserved-word list flags it as a likely framework route before launch, giving the team a chance to rename it to something like /api-pricing instead of discovering the conflict in production.

When a slug also needs to be a variable name

Quick answerURL slugs use kebab-case, but the same source title is often reused elsewhere in a migration as a JSON key, a database column, a component file name, or a JavaScript variable — contexts that expect camelCase, snake_case, or PascalCase instead. Converting one input into every common naming convention at once avoids retyping and reformatting it by hand for each file.

During a rebuild it's common to take the same page title and derive several different identifiers from it: top-10-coffee-makers as the URL, topTenCoffeeMakers as a component prop, TOP_10_COFFEE_MAKERS as a constant key, and top_10_coffee_makers as a database slug column. Doing that conversion by hand for dozens of pages is tedious and error-prone — a naming-case tool that shows kebab-case, snake_case, camelCase, PascalCase, and a few others side by side for the same input saves that manual step.

Same source title, different naming conventions
ConventionTypical useExample
kebab-caseURL slugtop-10-coffee-makers
snake_caseDatabase column / config keytop_10_coffee_makers
camelCaseJS variable / component proptop10CoffeeMakers
PascalCaseComponent file nameTop10CoffeeMakers
CONSTANT_CASEEnvironment / constant keyTOP_10_COFFEE_MAKERS

Building a redirect map before launch

Quick answerGenerate old-URL-to-new-slug pairs for the whole site as a downloadable file (old title or path in one column, new slug in the next), then feed that mapping into your redirect rules — a .htaccess block, an Nginx map, or your framework's redirect config — before the new site goes live.

The riskiest part of any URL migration isn't generating the new slugs — it's making sure every old address that search engines or external links already know about still resolves to something, via a 301, instead of a 404. Having the old-title-to-new-slug pairs available as a plain CSV makes it straightforward to hand that list to whoever owns the server config, or to paste it directly into a spreadsheet for a final review pass before launch.

It's worth treating this step as non-optional even for pages that seem low-traffic. A page that ranks for a long-tail query you're not tracking closely can still lose that ranking permanently if its old URL starts returning a 404 with no redirect in place.

Paste your full batch of old titles or URLs and generate every new slug at once — bulk mode, reserved-word checking, and naming-case conversion, all in one free browser tool.

Try the free Slug Generator →

Frequently asked questions

What's the first step before migrating a site's URL structure?
Export every existing URL (or page title) into a single list first, then batch-convert that whole list into new slugs at once rather than page by page. Generating them together, in one pass, is what makes it possible to catch duplicate collisions before launch instead of discovering them one broken link at a time afterward.
How do I avoid a new slug colliding with a reserved route in my app?
Check each candidate slug against your framework's reserved paths — common ones include admin, api, login, category, tag, and static asset folders like assets or static. A slug that happens to match one of these can silently break routing or shadow a real page, so it's worth checking new slugs against a reserved-word list before they go live, especially during a bulk migration.
Why would I need a slug in camelCase or snake_case instead of kebab-case?
URL slugs use kebab-case, but the same source title often needs to become a variable name, a JSON key, a database column, or a component file name elsewhere in the same migration — and those contexts typically expect camelCase, snake_case, or PascalCase instead. Converting the same input into every common naming convention at once saves manually retyping and reformatting it for each file.
How do I build a redirect map for a large batch of changed URLs?
Generate old-slug-to-new-slug pairs for every page as a CSV (old title/URL in one column, new slug in the next), then feed that CSV into your redirect rules — a .htaccess block, an Nginx map, or your framework's redirect config. Having the mapping as a downloadable file makes it easy to hand off to whoever configures the server, and easy to audit before launch.
Should every old URL get a 1:1 redirect during a migration?
Ideally yes, for any URL that has ever been indexed or linked to externally. Skipping redirects for pages you assume have no traffic is a common way migrations quietly lose search rankings — a 404 on a page that used to rank costs more than the few minutes it takes to add one more redirect rule.

Related guides

A note on this guide: the worked examples above use illustrative, hypothetical titles and page names to demonstrate how a migration checklist applies — they are not claims about any specific real website's traffic, rankings, or migration outcome. This content is for general informational purposes and isn't a substitute for your framework's own routing documentation or a developer's review of your specific server configuration.