diff --git a/facets_pretty_paths.services.yml b/facets_pretty_paths.services.yml
index 90a4da2..03b8959 100644
--- a/facets_pretty_paths.services.yml
+++ b/facets_pretty_paths.services.yml
@@ -1,8 +1,9 @@
 services:
-  facets_pretty_paths.path_processor:
-    class: Drupal\facets_pretty_paths\PathProcessorPrettyPaths
+  facets_pretty_paths.route_subscriber:
+    class: Drupal\facets_pretty_paths\RouteSubscriber
+    arguments: ['@plugin.manager.facets.facet_source']
     tags:
-      - { name: path_processor_inbound, priority: 80 }
+      - { name: event_subscriber }
   plugin.manager.facets_pretty_paths.coder:
     class: Drupal\facets_pretty_paths\Coder\CoderPluginManager
     parent: default_plugin_manager
diff --git a/src/PathProcessorPrettyPaths.php b/src/PathProcessorPrettyPaths.php
deleted file mode 100644
index a427e85..0000000
--- a/src/PathProcessorPrettyPaths.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-namespace Drupal\facets_pretty_paths;
-
-use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
-use Symfony\Component\HttpFoundation\Request;
-
-/**
- * Path processor for facets_pretty_paths.
- */
-class PathProcessorPrettyPaths implements InboundPathProcessorInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function processInbound($path, Request $request) {
-
-    // TODO: check if we can do this faster, now every url requires a load of all facet sources once (its cached later though)
-    $facet_source_plugin_manager = \Drupal::service('plugin.manager.facets.facet_source');
-    $facet_sources = $facet_source_plugin_manager->getDefinitions();
-
-    // If path starts with an url having a facet source, reroute all subpaths to
-    // the facet source.
-    foreach ($facet_sources as $facet_source) {
-      $facet_source_plugin = $facet_source_plugin_manager->createInstance($facet_source['id']);
-      $facet_source_path = $facet_source_plugin->getPath();
-      if ($path && strpos($path, $facet_source_path, 0) === 0 && strlen($facet_source_path) > 1) {
-        $path = $facet_source_path;
-        // Add an attribute to prevent that the Redirect Module redirects to the
-        // canonical URL when "Enforce clean and canonical URLs" is selected.
-        // We use the request object directly as $request is a cloned object
-        // made in RedirectRequestSubscriber::onKernelRequestCheckRedirect.
-        \Drupal::request()->attributes->set('_disable_route_normalizer', TRUE);
-      }
-    }
-
-    return $path;
-  }
-
-}
diff --git a/src/Plugin/facets/url_processor/FacetsPrettyPathsUrlProcessor.php b/src/Plugin/facets/url_processor/FacetsPrettyPathsUrlProcessor.php
index d548fd3..827c6bb 100644
--- a/src/Plugin/facets/url_processor/FacetsPrettyPathsUrlProcessor.php
+++ b/src/Plugin/facets/url_processor/FacetsPrettyPathsUrlProcessor.php
@@ -2,10 +2,15 @@
 
 namespace Drupal\facets_pretty_paths\Plugin\facets\url_processor;
 
+use Drupal\Core\Routing\ResettableStackedRouteMatchInterface;
 use Drupal\Core\Url;
 use Drupal\facets\FacetInterface;
 use Drupal\facets\UrlProcessor\UrlProcessorPluginBase;
 use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Pretty paths URL processor.
@@ -16,25 +21,98 @@ use Symfony\Component\HttpFoundation\Request;
  *   description = @Translation("Pretty paths uses slashes as separator, e.g. /brand/drupal/color/blue"),
  * )
  */
-class FacetsPrettyPathsUrlProcessor extends UrlProcessorPluginBase {
+class FacetsPrettyPathsUrlProcessor extends UrlProcessorPluginBase implements ContainerFactoryPluginInterface {
 
   /**
+   * Array with active filters.
+   *
    * @var array
    *   An array containing the active filters
    */
   protected $activeFilters = [];
 
   /**
-   * {@inheritdoc}
+   * The language manager.
+   *
+   * @var \Drupal\Core\Language\LanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * The config factory service.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The current_route_match service.
+   *
+   * @var \Drupal\Core\Routing\ResettableStackedRouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs FacetsPrettyPathsUrlProcessor object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   A request object for the current request.
+   * @param \Drupal\Core\Routing\ResettableStackedRouteMatchInterface $routeMatch
+   *   The route match service.
+   * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
+   *   The language manager.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, Request $request, ResettableStackedRouteMatchInterface $routeMatch, LanguageManagerInterface $languageManager, ConfigFactoryInterface $config_factory) {
     parent::__construct($configuration, $plugin_id, $plugin_definition, $request);
+    $this->languageManager = $languageManager;
+    $this->configFactory = $config_factory;
+    $this->routeMatch = $routeMatch;
     $this->initializeActiveFilters($configuration);
   }
 
   /**
    * {@inheritdoc}
    */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('request_stack')->getMasterRequest(),
+      $container->get('current_route_match'),
+      $container->get('language_manager'),
+      $container->get('config.factory')
+    );
+  }
+
+  /**
+   * Returns current language path prefix.
+   *
+   * @return string
+   *   Current language path prefix
+   */
+  protected function getLanguageUrlPrefix() {
+    $language = $this->languageManager->getCurrentLanguage();
+    $config = $config = $this->configFactory->get('language.negotiation');
+    $prefixes = $config->get('url.prefixes');
+    $language_url_prefix = '';
+    if (!empty($prefixes[$language->getId()])) {
+      $language_url_prefix = '/' . $prefixes[$language->getId()];
+    }
+    return $language_url_prefix;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function buildUrls(FacetInterface $facet, array $results) {
 
     // No results are found for this facet, so don't try to create urls.
@@ -42,13 +120,11 @@ class FacetsPrettyPathsUrlProcessor extends UrlProcessorPluginBase {
       return [];
     }
 
-    $current_path = rtrim($this->request->getPathInfo(), '/');
-    $facet_source_path = $facet->getFacetSource()->getPath();
-    $facet_source_path_length = strlen($facet_source_path);
-    $filters = '';
-    if(substr($current_path, 0, $facet_source_path_length) === $facet_source_path){
-      $filters = substr($current_path, $facet_source_path_length);
+    $filters = $this->routeMatch->getParameter('facets_query');
+    if (!empty($filters)) {
+      $filters = "/" . $filters;
     }
+
     $coder_plugin_manager = \Drupal::service('plugin.manager.facets_pretty_paths.coder');
     $coder_id = $facet->getThirdPartySetting('facets_pretty_paths', 'coder', 'default_coder');
     $coder = $coder_plugin_manager->createInstance($coder_id, ['facet' => $facet]);
@@ -97,7 +173,11 @@ class FacetsPrettyPathsUrlProcessor extends UrlProcessorPluginBase {
         }
       }
 
-      $url = Url::fromUri('base:' . $facet->getFacetSource()->getPath() . $filters_current_result);
+      // Strip the leading slash before forwarding as a route paramter.
+      $parameters = $this->routeMatch->getParameters()->all();
+      $parameters['facets_query'] = ltrim($filters_current_result, '/');
+
+      $url = Url::fromRoute($this->routeMatch->getRouteName(), $parameters);
 
       // First get the current list of get parameters.
       $get_params = $this->request->query;
@@ -142,13 +222,7 @@ class FacetsPrettyPathsUrlProcessor extends UrlProcessorPluginBase {
    * active values for a specific facet are added to the facet.
    */
   protected function initializeActiveFilters($configuration) {
-    if ($configuration['facet']) {
-      $facet_source_path = $configuration['facet']->getFacetSource()->getPath();
-    }
-
-    $path = $this->request->getPathInfo();
-    if (strpos($path, $facet_source_path, 0) === 0) {
-      $filters = substr($path, (strlen($facet_source_path) + 1));
+    if ($filters = $this->routeMatch->getParameter('facets_query')) {
       $parts = explode('/', $filters);
       if(count($parts) % 2 !== 0){
         // Our key/value combination should always be even. If uneven, we just
diff --git a/src/RouteSubscriber.php b/src/RouteSubscriber.php
new file mode 100644
index 0000000..25093e2
--- /dev/null
+++ b/src/RouteSubscriber.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Drupal\facets_pretty_paths;
+
+use Drupal\Core\Routing\RouteSubscriberBase;
+use Drupal\Core\Url;
+use Drupal\facets\FacetSource\FacetSourcePluginManager;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Alter facet source routes, adding a parameter.
+ */
+class RouteSubscriber extends RouteSubscriberBase {
+
+  /**
+   * Service plugin.manager.facet_source.
+   *
+   * @var \Drupal\facets\FacetSource\FacetSourcePluginManager
+   */
+  protected $facetSourcePluginManager;
+
+  /**
+   * Constructs a RouteSubscriber object.
+   *
+   * @param Drupal\facets\FacetSource\FacetSourcePluginManager $facetSourcePluginManager
+   *   The plugin.manager.facets.facet_source service.
+   */
+  public function __construct(FacetSourcePluginManager $facetSourcePluginManager) {
+    $this->facetSourcePluginManager = $facetSourcePluginManager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alterRoutes(RouteCollection $collection) {
+    $sources = $this->facetSourcePluginManager->getDefinitions();
+    foreach ($sources as $source) {
+      $sourcePlugin = $this->facetSourcePluginManager->createInstance($source['id']);
+      $path = $sourcePlugin->getPath();
+
+      try {
+        $url = Url::fromUri('internal:' . $path);
+        $sourceRoute = $collection->get($url->getRouteName());
+
+        if ($sourceRoute) {
+          $sourceRoute->setPath($sourceRoute->getPath() . '/{facets_query}');
+          $sourceRoute->setDefault('facets_query', '');
+          $sourceRoute->setRequirement('facets_query', '.*');
+
+          // Core improperly checks for route parameters that can have a slash
+          // in them, only making the route match for parameters that don't
+          // have a slash.
+          // Workaround that here by adding fake optional parameters to the
+          // route, that'll never be filled, and won't get any value set because
+          // {facets_query} will already have matched the whole path.
+          // Note that until the core bug is resolved, the path maximum length
+          // of 255 in the router table induces a limit to the number of facets
+          // that can be triggered, which will depend on the facets source path
+          // length. For a base path of "/search", 40 placeholders can be added,
+          // which means 20 active filter pairs.
+          // See https://www.drupal.org/project/drupal/issues/2741939
+          $routePath = $sourceRoute->getPath();
+
+          for ($i = 0; strlen($routePath) < 250; $i++) {
+            $sourceRoute->setDefault('f' . $i, '');
+            $routePath .= "/{f{$i}}";
+          }
+
+          $sourceRoute->setPath($routePath);
+        }
+      }
+      catch (\Exception $e) {
+
+      }
+
+    }
+
+  }
+
+}
