WordPress Plugins
Free Tools
Claude Skills
Pricing Blog Case Studies Switch to Royal Plugin Graveyard Support My Account Cart
Support / Royal Links / Coexistence with Other Link Plugins

Coexistence with Other Link Plugins

Royal Links is designed to run alongside Pretty Links, ThirstyAffiliates, BetterLinks, or Simple URLs while you migrate. You do not need to deactivate the other plugin first. This page covers the coexistence notice you’ll see on Royal Links admin pages, how URL-prefix conflicts are detected and blocked, what happens when import slugs collide with existing Royal Links, and how to extend the built-in detection registry for plugins we don’t yet recognize.

TL;DR

Running Pretty Links (or ThirstyAffiliates / BetterLinks / Simple URLs) alongside Royal Links is a supported state, not a warning. The two coexist cleanly during your transition. Royal Links only handles redirect slugs you create in Royal Links; anything else falls through to whichever plugin owns that slug. Prefix collisions are detected and blocked at settings-save time. Slug collisions during import are logged with a one-click retry that appends a -1 suffix.

The migration-mode notice

When Royal Links detects one of the recognized link plugins active on your site, it renders a supportive notice at the top of every Royal Links admin page. The notice looks like this:

Migrating from Pretty Links?

Royal Links sees N live redirects on this site. Import them into Royal Links, or keep both plugins running side-by-side during the transition — the two coexist cleanly. Continue migration →

The count reflects the live entries in the other plugin’s own database or custom post type. The Continue migration → button jumps straight to the Import/Export tab with the correct source pre-selected.

What the notice does not do

Dismissing the notice

Click the × in the top-right corner of the notice to dismiss it. Dismissal is per-user and per-competitor:

Recognized plugins

The built-in registry recognizes six competitor plugins out of the box. If yours isn’t here, jump to Extending the registry.

Plugin Plugin basename Migration wired?
Pretty Linkspretty-link/pretty-link.phpYes
Pretty Links Propretty-links-pro/pretty-link-pro.phpYes (uses the Pretty Links migrator)
ThirstyAffiliatesthirstyaffiliates/thirstyaffiliates.phpYes
BetterLinksbetterlinks/better-links.phpYes
BetterLinks Probetterlinks-pro/betterlinks-pro.phpYes (uses the BetterLinks migrator)
Simple URLssimple-urls/simple-urls.phpNotice only (no migrator yet)

How to migrate

The safe pattern for migrating from another link plugin to Royal Links is to run both plugins in parallel while you verify each set of imported links, then deactivate the source plugin once you’re confident.

Install and activate Royal Links

Search for “Royal Links” in your WordPress Plugins screen, click Install, then Activate. The other plugin stays active.

Go to Import/Export

In wp-admin, navigate to Links → Import/Export under the Royal Links menu (or click Continue migration → on the notice at the top of any Royal Links admin page).

Migrate one source at a time

Under “Migrate from another plugin,” you’ll see a card for each recognized source with a link count. Click Migrate. The importer runs in batches of 500 by default (adjust with the royal_links_import_limit filter). If the source has more than 500 links, click Migrate again to continue.

Review the imported links

Under Links → All Links, verify that a sample of imports look right: target URL preserved, redirect type preserved, nofollow / sponsored flags preserved, categories mapped. If anything is off, the source plugin is still active and untouched — nothing was lost.

Test one or two migrated URLs

Open a Royal Links slug in a new tab. It should redirect to the destination. The corresponding entry in the source plugin still exists too — both slugs resolve to the same destination during the parallel period, so no reader-facing link goes dead while you migrate.

Deactivate the source plugin when ready

When you’re confident the Royal Links copy is complete and correct, deactivate the source plugin from Plugins → Installed Plugins. Delete the plugin only after you’ve confirmed all its rewrite rules have flushed (visit any Royal Links slug to prompt WP to rebuild rewrites).

The parallel period is intentional

Royal Links only handles slugs that exist as royal_link posts. Every other slug on your prefix falls through to the next template_redirect handler, which lets the source plugin keep serving its own URLs. You can migrate one link at a time and none of the older ones break in the interim.

URL prefix conflicts

Every link-management plugin owns a URL prefix on your site (Royal Links defaults to /go/). If two active plugins try to own the same prefix, their rewrite rules fight and one plugin’s links stop resolving. Royal Links blocks this at the Settings save moment, before the collision reaches the reader.

What triggers a block

When you save a new Royal Links prefix under Links → Settings, the plugin checks the incoming value against three things:

  1. An active competitor with the same runtime prefix. If Pretty Links is active and its current prefix is empty (root), and you try to set Royal Links to empty, that’s a real conflict. Save is blocked. You’ll see a red admin notice: “The prefix you chose collides with the URL prefix currently used by Pretty Links, which is active on this site. Save was blocked so both plugins can keep coexisting cleanly. Try go instead.”
  2. An existing custom post type’s rewrite slug. If any other plugin has registered a public CPT with a rewrite slug that matches your incoming prefix, save is blocked. WordPress would silently overwrite one rewrite with the other otherwise.
  3. A known default prefix of an inactive plugin— this is a warning, not a block. If you set Royal Links to recommends (ThirstyAffiliates’ default) while ThirstyAffiliates is not installed, the save proceeds but you’ll see a yellow heads-up: “Heads up: the prefix you chose matches the default URL prefix used by ThirstyAffiliates. That plugin is not currently active, so the change was saved — but if you install it later you will hit a collision.”

Fixing a block

Pick a different prefix. The block notice includes a suggestion (the requested prefix with -links appended, or go if you tried to save an empty prefix). Or pick anything that’s not the other plugin’s active prefix.

Bypassing the check

Two escape hatches exist for the rare case where the collision is intentional (e.g. you’re about to deactivate the other plugin in the same session and want to pre-configure the same prefix):

// wp-config.php — disables the check globally
define( 'ROYAL_LINKS_SKIP_COMPAT_PREFIX_CHECK', true );

Or, for conditional bypass:

// In a mu-plugin or your theme's functions.php
add_filter( 'royal_links_skip_prefix_collision_check', '__return_true' );
Bypass with care

Both bypass paths disable the check completely until you remove them. If you keep the bypass in place and then install a plugin that shares your prefix later, Royal Links won’t catch it and one of the two plugins’ redirects will silently stop working.

Slug conflicts during import

When you migrate from another link plugin, each source link is inserted as a royal_link post with the source’s slug. If a Royal Link with that exact slug already exists, Royal Links skips the insert rather than clobbering the existing post — because the existing post may already have click counts, per-link overrides, or A/B test data attached that you don’t want to lose.

The completion notice

After a migration run, the Import/Export page shows a summary like:

15 links migrated from Pretty Links. 3 skipped due to slug conflicts. 1 skipped for another reason (missing URL, etc.).

Below that, if any slug conflicts occurred, a details table renders inline:

Slug Title Destination URL
amazon-productAmazon Producthttps://amazon.com/dp/…
shareasale-offerShareASale Offerhttps://shareasale.com/r/…
direct-linkDirect Linkhttps://example.com/product

The one-click retry

Under the table you’ll see a Retry all with -1, -2, … suffix button. Clicking it:

  1. Reads every conflict in the current run.
  2. For each, tries slug + -1, then -2, up to -50, stopping at the first free slug.
  3. Calls the standard link-create pipeline with that free slug and the full args from the original source row (target URL, redirect type, nofollow / sponsored flags, categories, etc.).
  4. Redirects back with a summary: “Retried N conflict(s) with a suffix; M could not be retried.”

The retry is non-destructive. The pre-existing Royal Link with the base slug is never modified. The new imported links come in as separate posts with the suffix.

Buffer lifetime

The conflict details persist for 1 hour after a migration run, per user. Running a new migration replaces the buffer with the new run’s conflicts. Clicking Retry clears the buffer immediately after processing (successful or not).

Deciding what to do

Slug conflicts usually mean you’ve already imported this source plugin’s links once before (and are re-running the migration by mistake), OR you created a Royal Link manually with the same slug the source plugin uses. In the first case, ignore the conflicts — the links are already in Royal Links. In the second case, the retry-with-suffix path lets you keep both versions and reconcile manually.

How coexistence works when a reader clicks a link

When a reader hits a URL under your Royal Links prefix (say /go/apple), WordPress dispatches the request to Royal Links first. Royal Links checks whether a royal_link post with slug apple exists.

The upshot: during a partial migration, half your links can live in Royal Links and half in the source plugin, sharing the same prefix, without any reader-facing URL going dead. As you migrate each link, resolution just moves from one plugin to the other.

Restoring pre-2.0.10 behaviour

If you want the pre-2.0.10 behaviour (force a 404 immediately on a Royal Links slug miss), a filter is available:

// Force 404 on cache miss instead of falling through
add_filter( 'royal_links_missing_slug_fallthrough', '__return_false' );

Only useful if you’ve deliberately deactivated every other link plugin and want stricter 404 semantics.

Extending the detection registry

The built-in registry recognizes six plugins. If you’re running a link-management plugin the registry doesn’t know about (a private in-house tool, a niche third-party plugin, an older abandoned plugin), you can add it via a filter. Once added, that plugin will be included in prefix-collision detection and can trigger a migration notice if you also wire up a migrator on the WordPress side (out of scope for this filter — the filter only handles detection).

The royal_links_compat_plugins filter

add_filter( 'royal_links_compat_plugins', function ( $plugins ) {
    $plugins['rebrandly-toolbar'] = array(
        'name'           => 'Rebrandly Toolbar',
        'basename'       => 'rebrandly-toolbar/rebrandly.php',
        'migration_key'  => null,   // no migrator wired
        'default_prefix' => '',     // Rebrandly is edge-side, no local prefix
        'prefix_option'  => null,   // no WP option to read the runtime prefix from
    );
    return $plugins;
} );

Registry entry fields:

The filter runs once per admin page load. Once added, your custom entry behaves identically to a built-in entry: detection notice, per-user dismissal, prefix collision detection, and (if you wired a matching migration_key) the migration CTA.

Filters and constants reference

Name Type What it does
royal_links_compat_plugins Filter Add, modify, or remove entries in the detection registry. Runs once per admin page load.
royal_links_skip_prefix_collision_check Filter Return true from this filter to bypass the prefix-collision check on the next settings save. Runs inside the pre_update_option_royal_links_link_prefix filter chain.
ROYAL_LINKS_SKIP_COMPAT_PREFIX_CHECK Constant Define as true in wp-config.php to bypass the prefix-collision check globally.
royal_links_missing_slug_fallthrough Filter Default true. When Royal Links receives a request for a slug that doesn’t exist, this filter decides whether to bail silently (so other template_redirect handlers can try) or force a 404 immediately. Return false for pre-2.0.10 strict-404 behavior.
royal_links_import_limit Filter Default 500. Maximum number of links to import per Migrate button click. Raise or lower to tune batch size for very large source datastores.