ℹ Disclaimer: Content may contain affiliate links, WPThink.com may earn a commission from qualifying purchases.
How to Match WordPress Permalinks in Astro Without Breaking Links
A site can look finished while its highest-value URLs are already leaking traffic.
Google lands on /2021/07/sample-post/, but Astro now serves /blog/sample-post/. The page exists, yet the original address returns a 404 or a soft redirect chain. That gap is permalink drift—the most common post-migration failure because rendering success says nothing about historic URL parity.
In WordPress, slugs often encode dates, categories, attachment paths, pagination, and odd legacy rewrites from plugins. Miss even one pattern, and rankings, backlinks, bookmarks, and shared links degrade silently. Users hit dead ends; crawlers treat the old document as gone.
Map the full WordPress URL contract first
-
Extract the permalink rules
Record the active permalink structure, category and tag bases, trailing-slash behavior, pagination format, and any custom post type rewrites. These settings define more than single-post URLs.
-
List every public URL family
Include posts, pages, custom post types, taxonomies, author archives, date archives, media attachment pages, feeds, search results, and embed endpoints. WordPress often serves these even when they are rarely linked in navigation.
-
Capture secondary patterns
Add paged archives, comment-page URLs, old-slug redirects, multilingual prefixes, and plugin-created paths such as shop, event, or membership routes. These are usually where migrations miss parity.
-
Document normalization behavior
Note lowercase handling, percent-encoding, optional index.php, trailing-slash redirects, and canonical consolidation of duplicate paths. Astro routing must match both the visible path and WordPress’s correction rules.
-
Mark removals and redirect targets
For any pattern that will not exist in Astro, define the replacement URL and status code before launch. Silent omission is what breaks backlinks and inherited rankings.
A database dump reveals objects, not the full set of paths WordPress answers. Core, themes, and plugins can generate valid URLs through rewrite rules, canonical redirects, and legacy slug history.
The reliable inventory usually comes from combining:
a crawl of the live site server access logs WordPress rewrite and redirect settingsChoose the routing model that can keep up
Astro can mirror WordPress paths in static, SSR, or hybrid mode, but the long-term maintenance cost is very different.
Static builds
Static output is safest when URLs change rarely and content updates can wait for a rebuild. Every known route is generated ahead of time, so permalink parity stays predictable if the WordPress route inventory is complete. The risk appears at scale: missed archives, late editorial changes, or newly created slugs remain absent until the next deploy.
SSR
SSR fits sites where posts, taxonomy pages, or author archives change throughout the day. Requests are resolved at runtime, which makes it far easier to honor legacy path rules, lookups by slug, and redirect logic without rebuilding the entire site. The tradeoff is operational: cache strategy, origin latency, and failure handling now affect URL reliability.
Hybrid
A hybrid setup is often the practical middle ground:
- pre-render evergreen content and stable archives
- use SSR for high-churn sections
- keep redirect and normalization logic shared across both paths
The durable rule is simple: permalink matching succeeds when the rendering model matches the site’s update frequency. Otherwise, parity becomes a recurring cleanup task instead of a stable contract.
Let WordPress define the path
Astro should usually consume the permalink path, not recreate it from slugs, dates, and guessed parent rules. WordPress already knows the final public URL after permalink settings, custom post type rewrites, multilingual plugins, and term hierarchies have been applied. The safest field is the canonical path string returned by WordPress or derived from its permalink API.
Normalize before routing
Route drift often starts in string handling, not page generation. Normalize the path before Astro maps it:
- choose one trailing-slash policy and apply it everywhere
- percent-decode only where WordPress does; keep reserved characters stable
- collapse duplicate slashes
- resolve parent segments like
.and.. - preserve case rules consistently, especially on mixed hosting stacks
- strip domain, scheme, and query string unless they are part of routing
A stored canonical value such as /news/press-release/ is safer than rebuilding from {post_type}/{slug}. Rebuilding misses edge cases like nested pages, rewritten taxonomies, or filtered permalinks. Once normalized, Astro can match paths deterministically and attach redirects only where WordPress intentionally changed the URL.
If a migration pipeline can export each item’s final path from WordPress, Astro avoids guessing about rewrite logic later.
Build Astro routes from the URL map
Astro route files should follow the WordPress URL map, not an internal content taxonomy. If WordPress already serves /category/design/, /2024/06/post-slug/, and hierarchical pages like /company/about/, the filesystem should reflect those shapes first. That keeps matching logic readable and makes permalink parity testable.
A catch-all route such as src/pages/[...slug].astro works best when many paths share one resolver and one rendering pipeline. It is useful for hierarchical pages or mixed CMS-driven content, but it should not become a universal trap for every URL.
Use split routes when path families behave differently:
src/pages/category/[...slug].astrofor taxonomy archivessrc/pages/[year]/[month]/[day]/[slug].astrofor dated postssrc/pages/author/[slug].astrofor author archives- dedicated files for
feed,search,wp-json, or plugin-owned endpoints
This avoids collisions and makes route intent obvious. Even though Astro prioritizes more specific files, broad matchers still need a reserved-path denylist so CMS pages do not accidentally claim system URLs.
For nested content, match the full segment chain, not only the final slug. /services/seo/audits/ should resolve from ['services','seo','audits'], then be joined into the normalized WordPress path for lookup. That prevents false matches when identical child slugs exist under different parents.
The URL mismatches that usually get missed
Most failures appear first in archives, taxonomies, author pages, feeds, and paginated URLs.
A migrated article may resolve perfectly while /category/news/page/2/ or /author/name/feed/ quietly 404s. Those routes still attract crawlers, links, and returning visitors.
/page/2/ patterns often carry real traffic and index history.
WordPress archive pagination is part of the public path contract. If Astro changes the segment, removes it, or canonicalizes it differently, long-tail discovery drops fast.
Bases like /category/ and /tag/ are routing signals, not decoration.
Changing or stripping them alters thousands of URLs at once. Teams trying to preserve WordPress permalink patterns usually need these prefixes mapped explicitly.
Hierarchical paths depend on the full segment chain.
/docs/setup/cache/ is not equivalent to /cache/. If parent segments change, old child URLs break unless redirects or legacy aliases are kept intentionally.
Keeping every legacy pattern forever is not always necessary. What matters is making each break intentional: preserve high-value routes, redirect the rest cleanly, and document every exception before launch.
Add redirects and exceptions
Matching Astro routes only proves that current URLs resolve. A safe cutover also preserves every former WordPress path that still receives links, traffic, or crawler visits. Redirect rules usually come from three places: WordPress redirect plugins or .htaccess, SEO rewrites, and server logs showing repeated 404s.
- Platform redirects: Prefer edge or host-level rules on Netlify, Vercel, or Cloudflare so legacy paths resolve before Astro runs.
- Previews and drafts: Keep
/previewflows out of static routing; handle them with SSR, protected endpoints, or disable them. - Removed content: Return 410 Gone for intentionally deleted URLs, not blanket homepage redirects.
- Exceptions: Preserve feeds, search, attachments, and callback URLs only when they still serve a real purpose.
This is what turns route parity into a safe migration instead of a brief illusion.
Run the cutover checklist
-
Diff real URL sets
Export WordPress URLs from sitemaps, database tables, and redirect rules, then crawl Astro output and compare path-by-path. Include archives, pagination, feeds, media, and legacy aliases.
-
Check response behavior
Verify that each expected path returns the intended 200, 301, 404, or 410. Remove redirect chains, mixed trailing-slash behavior, and case-sensitive misses.
-
Validate page signals
Confirm canonicals, robots directives, hreflang, pagination tags, XML sitemaps, and structured data match the new paths. A correct route with a stale canonical still leaks authority.
-
Watch the first days after DNS
Review server logs, edge logs, Search Console coverage, and analytics landing pages for 404s, soft 404s, and redirect spikes. Backlink-heavy misses usually appear first.
A migration can look healthy while long-tail paths fail silently. Sample old URLs directly, especially paginated archives, parent-child pages, encoded slugs, and plugin-generated endpoints.
Treat parity as an operating habit
- Re-run diffs after content imports, plugin changes, or permalink setting changes.
- Keep a standing miss log and turn repeats into explicit rules.
Reliable permalink matching comes from a repeatable launch routine: compare URL inventories, verify technical signals, and monitor production traffic after cutover. Route files start the job; validation and feedback loops keep links intact.