Redirect based on query string I'm migrating a legacy blog from a home-grown CMS to Drupal 7 and I need to wrap my head around how I'm going to redirect URLS to a new aliased pattern.

The legacy site's URLs use query strings /?t=40&amp;an=49187&amp;anc=570&amp;format=xml which then redirect to an aliased url like /blog/i-know-this-is-not-ideal. Most of the listing pages on the site use the query parameters to link to pages, though others use the aliased urls. The an parameter appears to refer to their version of a Node ID, which I'm able to parse and store in my migration.

The company who owns this platform was kind enough to sent me an Excel spreadsheet with aliases in one column and query strings in another — so I have something at least.

Maintaining SEO juice is critical for this client — and Google has parsed these query parameters in many cases.

Should I look towards writing a custom module for this, as the Redirect module appears not to provide support for query parameters? Or should I look into htaccess rewrite rules?
I think a small custom module will probably be the method with the least overhead. You could store the legacy ID in a field during the migration and access it from there if the appropriate query string is set.

Very rough examples...

Drupal 7:

mymodule.module

function mymodule_init() {
    if (!empty($_GET['an'])) {
        $query = new \EntityFieldQuery();
        $result = $query-&gt;entityCondition('entity_type', 'node')
            -&gt;fieldCondition('field_old_id', 'value', $_GET['an'])
            -&gt;execute();

        if (!empty($result['node'])) {
            $nids = array_keys($result['node']);
            $nid = reset($nids);
            drupal_goto(url("node/$nid"), [], 301);
        }

    }
}


Drupal 8:

mymodule.services.yml:

services:
  mymodule.redirect_subscriber:
    class: Drupal\mymodule\RedirectSubscriber
    arguments: ['@entity_type.manager', '@path.alias_manager']
    tags:
      - { name: 'event_subscriber' }


src/RedirectSubscriber.php:

namespace Drupal\mymodule;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Path\AliasManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RedirectSubscriber implements EventSubscriberInterface
{

    protected $nodeStorage;

    protected $aliasManager;

    public function __construct(EntityTypeManagerInterface $entity_type_manager, AliasManagerInterface $alias_manager)
    {
        $this-&gt;nodeStorage = $entity_type_manager-&gt;getStorage('node');
        $this-&gt;aliasManager = $alias_manager;
    }

    public function Redirect(GetResponseEvent $event)
    {
        $old_id = $event-&gt;getRequest()-&gt;get('an');

        if (!empty($old_id)) {
            $ids = $this-&gt;nodeStorage-&gt;getQuery()
                -&gt;condition('field_old_id', intval($old_id))
                -&gt;execute();

            if (!empty($ids)) {
                $nid = reset($ids);
                $url = $this-&gt;aliasManager-&gt;getAliasByPath("/node/$nid");
                $event-&gt;setResponse(new RedirectResponse($url, 301));
            }
        }
    }

    static function getSubscribedEvents()
    {
        $events[KernelEvents::REQUEST][] = array('Redirect', 20);
        return $events;
    }
}