diff --git a/eu_cookie_compliance.module b/eu_cookie_compliance.module
index 39fb43f..1c2d7fb 100644
--- a/eu_cookie_compliance.module
+++ b/eu_cookie_compliance.module
@@ -17,6 +17,7 @@ use Drupal\Core\Language\LanguageManager;
 use Drupal\Core\Url;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Unicode;
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\Html;
 
 /**
@@ -60,97 +61,92 @@ function eu_cookie_compliance_page_attachments(&$attachments) {
 
   if ($config->get('popup_enabled') && \Drupal::currentUser()->hasPermission('display eu cookie compliance popup') && $geoip_match && $domain_allow && !$path_match) {
     $language = Drupal::languageManager()->getCurrentLanguage();
-    // Array storage for caching full client data.
 
-    $data = array();
-    if ($cache = \Drupal::cache()->get('eu_cookie_compliance_client_settings.' . $language->getId())) {
-      $data = $cache->data;
-    }
-    else {
-      // Initialize some needed popup settings messages.
-      $popup_settings_messages = array(
-        'popup_agree_button_message',
-        'popup_disagree_button_message',
-        'popup_hide_button_message',
-        'popup_find_more_button_message'
-      );
-      foreach ($popup_settings_messages as $key) {
-        if (!isset($popup_settings[$key])) {
-          $popup_settings[$key] = '';
-        }
-      }
-      $data['css'] = '';
-      // Color overrides.
-      if ($config->get('popup_bg_hex') !== '' and $config->get('popup_text_hex') !== '') {
-        $position = $config->get('popup_position') ? 'top' : 'bottom';
-        $data['css'] = '#sliding-popup.sliding-popup-' . $position . ' {background:#' . Html::escape($config->get('popup_bg_hex')) . ';}'
-             . '#sliding-popup .popup-content #popup-text h2, #sliding-popup .popup-content #popup-text p {color:#' . Html::escape($config->get('popup_text_hex')) . ' !important;}';
+    // Initialize some needed popup settings messages.
+    $popup_settings_messages = array(
+      'popup_agree_button_message',
+      'popup_disagree_button_message',
+      'popup_hide_button_message',
+      'popup_find_more_button_message'
+    );
+    foreach ($popup_settings_messages as $key) {
+      if (!isset($popup_settings[$key])) {
+        $popup_settings[$key] = '';
       }
-      $popup_text_info = str_replace(array("\r", "\n"), '', $config->get('popup_info.value'));
-      $popup_text_agreed = str_replace(array("\r", "\n"), '', $config->get('popup_agreed.value'));
-      $html_info = array(
-        '#theme' => 'eu_cookie_compliance_popup_info',
-        '#message' => check_markup($popup_text_info, $config->get('popup_info.format'), FALSE),
-        '#agree_button' => $config->get('popup_agree_button_message'),
-        '#disagree_button' => $config->get('popup_disagree_button_message'),
-      );
-      $html_agreed = array(
-        '#theme' => 'eu_cookie_compliance_popup_agreed',
-        '#message' => check_markup($popup_text_agreed, $config->get('popup_agreed.format'), FALSE),
-        '#hide_button' => $config->get('popup_hide_button_message'),
-        '#find_more_button' => $config->get('popup_find_more_button_message'),
-      );
-
-      $was_debugging = FALSE;
-
-      /**
-       * @var $twig_service Twig_Environment
-       */
-      $twig_service = \Drupal::service('twig');
-
-      if ($twig_service->isDebug()) {
-        $was_debugging = TRUE;
-        $twig_service->disableDebug();
-      }
-
-      $html_info = \Drupal::service('renderer')->renderRoot($html_info)->__toString();
-      $html_agreed = \Drupal::service('renderer')->renderRoot($html_agreed)->__toString();
+    }
+    $data['css'] = '';
+    // Color overrides.
+    if ($config->get('popup_bg_hex') !== '' and $config->get('popup_text_hex') !== '') {
+      $position = $config->get('popup_position') ? 'top' : 'bottom';
+      $data['css'] = '#sliding-popup.sliding-popup-' . $position . ' {background:#' . Html::escape($config->get('popup_bg_hex')) . ';}'
+           . '#sliding-popup .popup-content #popup-text h2, #sliding-popup .popup-content #popup-text p {color:#' . Html::escape($config->get('popup_text_hex')) . ' !important;}';
+    }
+    $popup_text_info = str_replace(array("\r", "\n"), '', $config->get('popup_info.value'));
+    $popup_text_agreed = str_replace(array("\r", "\n"), '', $config->get('popup_agreed.value'));
+    $html_info = array(
+      '#theme' => 'eu_cookie_compliance_popup_info',
+      '#message' => check_markup($popup_text_info, $config->get('popup_info.format'), FALSE),
+      '#agree_button' => $config->get('popup_agree_button_message'),
+      '#disagree_button' => $config->get('popup_disagree_button_message'),
+    );
+    $html_agreed = array(
+      '#theme' => 'eu_cookie_compliance_popup_agreed',
+      '#message' => check_markup($popup_text_agreed, $config->get('popup_agreed.format'), FALSE),
+      '#hide_button' => $config->get('popup_hide_button_message'),
+      '#find_more_button' => $config->get('popup_find_more_button_message'),
+    );
+
+    $was_debugging = FALSE;
+
+    /**
+     * @var $twig_service Twig_Environment
+     */
+    $twig_service = \Drupal::service('twig');
+
+    if ($twig_service->isDebug()) {
+      $was_debugging = TRUE;
+      $twig_service->disableDebug();
+    }
 
-      if ($was_debugging) {
-        $twig_service->enableDebug();
-      }
+    $html_info = \Drupal::service('renderer')->renderRoot($html_info)->__toString();
+    $html_agreed = \Drupal::service('renderer')->renderRoot($html_agreed)->__toString();
 
-      $domain_setting = $config->get('domain');
+    if ($was_debugging) {
+      $twig_service->enableDebug();
+    }
 
-      // Prepare internal links (remove the internal scheme).
-      $popup_link = $config->get('popup_link');
-      if (parse_url($popup_link, PHP_URL_SCHEME) === 'internal') {
-        $popup_link = explode(':', $popup_link, 2)[1];
-        $popup_link = \Drupal::service('path.alias_manager')->getAliasByPath($popup_link);
-      }
+    $domain_setting = $config->get('domain');
 
-      $data['variables'] = array(
-        'popup_enabled'        => $config->get('popup_enabled'),
-        'popup_agreed_enabled' => $config->get('popup_agreed_enabled'),
-        'popup_hide_agreed'    => $config->get('popup_hide_agreed'),
-        'popup_clicking_confirmation' => $config->get('popup_clicking_confirmation'),
-        'popup_html_info'      => $config->get('popup_enabled') ? $html_info : FALSE,
-        'popup_html_agreed'    => $config->get('popup_agreed_enabled') ? $html_agreed : FALSE,
-        'popup_height'         => !empty($config->get('popup_height')) ? $config->get('popup_height') : 'auto',
-        'popup_width'          => !empty($config->get('popup_width')) ? $config->get('popup_width') : '100%',
-        'popup_delay'          => (int) ($config->get('popup_delay') * 1000),
-        'popup_link'           => $config->get('popup_link'),
-        'popup_link_new_window' => $config->get('popup_link_new_window'),
-        'popup_link'           => $popup_link,
-        'popup_link_new_window' => !empty($config->get('popup_link_new_window')) ? $config->get('popup_link_new_window') : 1,
-        'popup_position'       => $config->get('popup_position'),
-        'popup_language'       => $language->getId(),
-        'popup_bg_hex'         => !empty($config->get('popup_bg_hex')) ? $config->get('popup_bg_hex') : FALSE,
-        'popup_text_hex'       => !empty($config->get('popup_text_hex')) ? $config->get('popup_text_hex') : FALSE,
-        'domain'               => $domain_setting,
-      );
-      \Drupal::cache()->set('eu_cookie_compliance_client_settings.' . $language->getId(), $data);
+    $popup_link = $config->get('popup_link');
+    if (UrlHelper::isExternal($popup_link)) {
+      $popup_link = Url::fromUri($popup_link);
+    }
+    else {
+      $popup_link = $popup_link === '<front>' ? '/' : $popup_link;
+      $popup_link = Url::fromUserInput($popup_link);
     }
+    $popup_link = $popup_link->toString();
+
+    $data['variables'] = array(
+      'popup_enabled'        => $config->get('popup_enabled'),
+      'popup_agreed_enabled' => $config->get('popup_agreed_enabled'),
+      'popup_hide_agreed'    => $config->get('popup_hide_agreed'),
+      'popup_clicking_confirmation' => $config->get('popup_clicking_confirmation'),
+      'popup_html_info'      => $config->get('popup_enabled') ? $html_info : FALSE,
+      'popup_html_agreed'    => $config->get('popup_agreed_enabled') ? $html_agreed : FALSE,
+      'popup_height'         => !empty($config->get('popup_height')) ? $config->get('popup_height') : 'auto',
+      'popup_width'          => !empty($config->get('popup_width')) ? $config->get('popup_width') : '100%',
+      'popup_delay'          => (int) ($config->get('popup_delay') * 1000),
+      'popup_link'           => $config->get('popup_link'),
+      'popup_link_new_window' => $config->get('popup_link_new_window'),
+      'popup_link'           => $popup_link,
+      'popup_link_new_window' => !empty($config->get('popup_link_new_window')) ? $config->get('popup_link_new_window') : 1,
+      'popup_position'       => $config->get('popup_position'),
+      'popup_language'       => $language->getId(),
+      'popup_bg_hex'         => !empty($config->get('popup_bg_hex')) ? $config->get('popup_bg_hex') : FALSE,
+      'popup_text_hex'       => !empty($config->get('popup_text_hex')) ? $config->get('popup_text_hex') : FALSE,
+      'domain'               => $domain_setting,
+    );
 
     $attachments['#attached']['drupalSettings']['eu_cookie_compliance'] = $data['variables'];
     $attachments['#attached']['library'][] = 'eu_cookie_compliance/eu_cookie_compliance';
@@ -191,3 +187,37 @@ function eu_cookie_compliance_validate_hex($element, FormStateInterface &$form_s
     $form_state->setError($element, t('%name must be a HEX value (without leading #) or empty.', array('%name' => $element['#title'])));
   }
 }
+
+function eu_cookie_compliance_validate_url($element, FormStateInterface &$form_state) {
+  if (!empty($element['#value'])) {
+    $input = $element['#value'];
+    if (UrlHelper::isExternal($input)) {
+      $allowed_protocols = ['http', 'https'];
+      if (!in_array(parse_url($input, PHP_URL_SCHEME), $allowed_protocols)) {
+        $form_state->setError($element, t('Invalid protocol specified for the %name (valid protocols: %protocols).', array('%name' => $element['#title'], '%protocols' => implode(', ', $allowed_protocols))));
+      }
+      else {
+        try {
+          Url::fromUri($input);
+        }
+        catch (Exception $exc) {
+          $form_state->setError($element, t('Invalid %name (:message).', array('%name' => $element['#title'], ':message' => $exc->getMessage())));
+        }
+      }
+    }
+    else {
+      // Internal URL.
+
+      // Special case for '<front>'.
+      if ($input === '<front>') {
+        $input = '/';
+      }
+      try {
+        Url::fromUserInput($input);
+      }
+      catch (Exception $exc) {
+        $form_state->setError($element, t('Invalid URL in %name field (:message).', array('%name' => $element['#title'], ':message' => $exc->getMessage())));
+      }
+    }
+  }
+}
diff --git a/src/Form/EuCookieComplianceConfigForm.php b/src/Form/EuCookieComplianceConfigForm.php
index 8f84c01..a9035dd 100644
--- a/src/Form/EuCookieComplianceConfigForm.php
+++ b/src/Form/EuCookieComplianceConfigForm.php
@@ -201,6 +201,7 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
       '#maxlength' => 220,
       '#required' => TRUE,
       '#description' => $this->t('Enter link to your privacy policy or other page that will explain cookies to your users. Internal links should start with a forward slash (/), external links should start with http:// or https://.'),
+      '#element_validate' => array('eu_cookie_compliance_validate_url'),
     );
 
     $form['eu_cookie_compliance']['popup_link_new_window'] = array(
@@ -299,41 +300,6 @@ class EuCookieComplianceConfigForm extends ConfigFormBase {
   /**
    * {@inheritdoc}
    */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    if (!$form_state->isValueEmpty('popup_link')) {
-      $popup_link = $form_state->getValue('popup_link');
-
-      // If the popup link points does not point to an external resource,
-      // prepend the 'internal:' scheme.
-      if (parse_url($popup_link, PHP_URL_SCHEME) === NULL) {
-        if (!in_array($popup_link[0], ['/'])) {
-          $form_state->setErrorByName('popup_link', $this->t('Internal paths should start with a "/".'));
-        }
-        else {
-          $popup_link = 'internal:' . $popup_link;
-
-          // If the link contains a fragment then check if it validates then
-          // rewrite link with full url.
-          if ((strpos($popup_link, '#') !== FALSE)) {
-            $fragment = explode('#', $popup_link);
-            $link = Url::fromUri($fragment[0], array(
-              'fragment' => $fragment[1],
-              'absolute' => TRUE,
-            ));
-            $form_state->setErrorByName('popup_link', $this->t('Looks like your privacy policy link contains fragment #, you should make this an absolute url eg @link', array('@link' => $link->toString())));
-          }
-
-          $form_state->setValueForElement($form['eu_cookie_compliance']['popup_link'], $this->aliasManager->getPathByAlias($popup_link));
-        }
-      }
-    }
-
-    parent::validateForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->config('eu_cookie_compliance.settings')
       ->set('domain', $form_state->getValue('domain'))
diff --git a/src/Tests/EuCookieComplianceConfigFormTest.php b/src/Tests/EuCookieComplianceConfigFormTest.php
index 8af4996..635a136 100644
--- a/src/Tests/EuCookieComplianceConfigFormTest.php
+++ b/src/Tests/EuCookieComplianceConfigFormTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\eu_cookie_compliance\Tests;
 
+use Drupal\Core\Url;
+
 /**
  * Test functionality for EU Cookie Compliance Config form.
  *
@@ -23,7 +25,9 @@ class EuCookieComplianceConfigFormTest extends EuCookieComplianceTestBase {
    */
   public static $modules = [
     'eu_cookie_compliance',
-    'eu_cookie_compliance_test'
+    'eu_cookie_compliance_test',
+    'node',
+    'path',
   ];
 
   /**
@@ -32,14 +36,15 @@ class EuCookieComplianceConfigFormTest extends EuCookieComplianceTestBase {
   protected function setUp() {
     parent::setUp();
     // Create and log in admin user.
-    $this->adminUser = $this->drupalCreateUser(['display eu cookie compliance popup', 'administer eu cookie compliance popup']);
-    $this->drupalLogin($this->adminUser);
+    $this->adminUser = $this->drupalCreateUser(['display eu cookie compliance popup', 'administer eu cookie compliance popup', 'access content', 'administer url aliases']);
+    $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
   }
 
   /**
    * Tests the EuCookieComplianceConfigForm.
    */
   public function testEuCookieComplianceConfigForm() {
+    $this->drupalLogin($this->adminUser);
     $this->drupalGet('admin/config/system/eu-cookie-compliance');
     $this->assertNoFieldChecked('edit-popup-enabled');
     $edit = ['popup_enabled' => 1];
@@ -53,4 +58,67 @@ class EuCookieComplianceConfigFormTest extends EuCookieComplianceTestBase {
     $this->assertText('The configuration options have been saved.');
   }
 
+  /**
+   * Tests the popup link validation and configuration.
+   */
+  function testPopupLinks() {
+    $this->drupalLogin($this->adminUser);
+
+    // Create 2 nodes.
+    $this->createNode();
+    $this->createNode();
+
+    // Set a path alias for the second node.
+    $this->drupalPostForm('/admin/config/search/path/add', ['source' => '/node/2', 'alias' => '/alias'], t('Save'));
+
+    $scenarios = [
+      // Format: User-entered value, value displayed in form, actual value for link.
+
+      // External URLs.
+      ['http://example.com/', 'http://example.com/', 'http://example.com/'],
+      ['https://drupal.org', 'https://drupal.org', 'https://drupal.org'],
+
+      // Internal URL without alias.
+      ['/node/1', '/node/1', '/node/1'],
+
+      // Internal URL with alias.
+      ['/node/2', '/node/2', '/alias'],
+
+      // Internal URL with alias with fragment.
+      ['/node/2#anchor', '/node/2#anchor', '/alias#anchor'],
+
+      // Special-case URLs.
+      ['<front>', '<front>', '/'],
+
+      // Spaces.
+      ['/lorem ipsum', '/lorem ipsum', '/lorem%20ipsum'],
+    ];
+
+    foreach ($scenarios as $scenario) {
+      // Configure EU cookie compliance.
+      $edit = ['popup_link' => $scenario[0], 'popup_enabled' => TRUE];
+      $this->drupalPostForm('/admin/config/system/eu-cookie-compliance', $edit, t('Save configuration'));
+
+      // Verify the popup link input field after submit.
+      $this->assertFieldByXpath('//input[@id="edit-popup-link"]', $scenario[1]);
+
+      // Load a page and verify the popup link in the page settings.
+      $this->drupalGet('/node/1');
+      $settings = $this->getDrupalSettings();
+      $this->assertEqual($settings['eu_cookie_compliance']['popup_link'], $scenario[2]);
+    }
+
+    // Test validation for the popup link setting.
+    $scenarios = [
+      'node/1' => "The user-entered string &#039;node/1&#039; must begin with a &#039;/&#039;, &#039;?&#039;, or &#039;#&#039;.",
+      'ftp://example.com' => "Invalid protocol specified for",
+    ];
+
+    foreach ($scenarios as $input => $message) {
+      $edit = ['popup_link' => $input];
+      $this->drupalPostForm('/admin/config/system/eu-cookie-compliance', $edit, t('Save configuration'));
+      $this->assertRaw($message);
+    }
+  }
+
 }
