diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index b8fcdeb..f2e17d8 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -122,6 +122,7 @@ public static function createFromPath($path) {
     else {
       // Look up the route name and parameters used for the given path.
       try {
+        $path = \Drupal::service('path.alias_manager.cached')->getSystemPath($path);
         $result = \Drupal::service('router')->match('/' . $path);
       }
       catch (ResourceNotFoundException $e) {
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
index 850c19e..74d9e72 100644
--- a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldType/LinkItem.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\link\Plugin\Field\FieldType;
 
+use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
@@ -62,6 +63,13 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
   /**
    * {@inheritdoc}
    */
+  public static function mainPropertyName() {
+    return 'url';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public static function schema(FieldStorageDefinitionInterface $field_definition) {
     return array(
       'columns' => array(
@@ -135,6 +143,29 @@ public function instanceSettingsForm(array $form, array &$form_state) {
   /**
    * {@inheritdoc}
    */
+  public function preSave() {
+    // Trim any spaces around the link text.
+    $this->title = trim($this->title);
+
+    $parsed_url = UrlHelper::parse(trim($this->url));
+    $this->url = $parsed_url['path'];
+    $this->options = ($this->options) ?: array();
+
+    // The link 'query' and 'fragment' parts need to be split and updated only
+    // if they exist (e.g. when the 'url' property is new or updated).
+    $options = array();
+    if (!empty($parsed_url['query'])) {
+      $options['query'] = $parsed_url['query'];
+    }
+    if (!empty($parsed_url['fragment'])) {
+      $options['fragment'] = $parsed_url['fragment'];
+    }
+    $this->options = $options + $this->options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function isEmpty() {
     $value = $this->get('url')->getValue();
     return $value === NULL || $value === '';
@@ -147,4 +178,19 @@ public function isExternal() {
     // External links don't have a route_name value.
     return empty($this->route_name);
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setValue($values, $notify = TRUE) {
+    // Unserialize the values.
+    // @todo The storage controller should take care of this.
+    foreach (array('route_parameters', 'options') as $property) {
+      if (isset($values[$property]) && is_string($values[$property])) {
+        $values[$property] = unserialize($values[$property]);
+      }
+    }
+    parent::setValue($values, $notify);
+  }
+
 }
diff --git a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php
index baf1eb5..77951e8 100644
--- a/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/lib/Drupal/link/Plugin/Field/FieldWidget/LinkWidget.php
@@ -205,22 +205,10 @@ public function massageFormValues(array $values, array $form, array &$form_state
     foreach ($values as &$value) {
       if (!empty($value['url'])) {
         try {
-          $parsed_url = UrlHelper::parse($value['url']);
-
-          // If internal links are supported, look up whether the given value is
-          // a path alias and store the system path instead.
-          if ($this->supportsInternalLinks() && !UrlHelper::isExternal($value['url'])) {
-            $parsed_url['path'] = \Drupal::service('path.alias_manager.cached')->getSystemPath($parsed_url['path']);
-          }
-
-          $url = Url::createFromPath($parsed_url['path']);
-          $url->setOption('query', $parsed_url['query']);
-          $url->setOption('fragment', $parsed_url['fragment']);
+          $url = Url::createFromPath($value['url']);
           $url->setOption('attributes', $value['attributes']);
 
           $value += $url->toArray();
-          // Reset the URL value to contain only the path.
-          $value['url'] = $parsed_url['path'];
         }
         catch (NotFoundHttpException $e) {
           // Nothing to do here, LinkTypeConstraintValidator emits errors.
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Controller/ShortcutSetController.php b/core/modules/shortcut/lib/Drupal/shortcut/Controller/ShortcutSetController.php
index e63e027..3a1db6a 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Controller/ShortcutSetController.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Controller/ShortcutSetController.php
@@ -8,6 +8,7 @@
 namespace Drupal\shortcut\Controller;
 
 use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Url;
 use Drupal\shortcut\ShortcutSetInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -39,7 +40,9 @@ public function addShortcutLinkInline(ShortcutSetInterface $shortcut_set, Reques
       $shortcut = $this->entityManager()->getStorage('shortcut')->create(array(
         'title' => $name,
         'shortcut_set' => $shortcut_set->id(),
-        'path' => $link,
+        'link' => array(
+          'url' => $link,
+        ) + Url::createFromPath($link)->toArray(),
       ));
 
       try {
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php b/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php
index 00d0dd3..839adf7 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Entity/Shortcut.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\FieldDefinition;
 use Drupal\Core\Url;
+use Drupal\link\LinkItemInterface;
 use Drupal\shortcut\ShortcutInterface;
 
 /**
@@ -58,7 +59,7 @@ public function getTitle() {
    */
   public function setTitle($link_title) {
     $this->set('title', $link_title);
-   return $this;
+    return $this;
   }
 
   /**
@@ -80,14 +81,14 @@ public function setWeight($weight) {
    * {@inheritdoc}
    */
   public function getRouteName() {
-    return $this->get('route_name')->value;
+    return $this->get('link')->route_name;
   }
 
   /**
    * {@inheritdoc}
    */
   public function setRouteName($route_name) {
-    $this->set('route_name', $route_name);
+    $this->get('link')->route_name = $route_name;
     return $this;
   }
 
@@ -95,38 +96,32 @@ public function setRouteName($route_name) {
    * {@inheritdoc}
    */
   public function getRouteParams() {
-    $value = $this->get('route_parameters')->getValue();
-    return reset($value);
+    return $this->get('link')->route_parameters;
   }
 
   /**
    * {@inheritdoc}
    */
   public function setRouteParams($route_parameters) {
-    $this->set('route_parameters', array('value' => $route_parameters));
-    return $this;
+    $this->get('link')->route_parameters = $route_parameters;
   }
 
   /**
    * {@inheritdoc}
    */
-  public static function preCreate(EntityStorageInterface $storage, array &$values) {
-    parent::preCreate($storage, $values);
-
-    if (!isset($values['shortcut_set'])) {
-      $values['shortcut_set'] = 'default';
-    }
+  public function getUrl() {
+    return new Url($this->link->route_name, (array) $this->link->route_parameters, (array) $this->link->options);
   }
 
   /**
    * {@inheritdoc}
    */
-  public function preSave(EntityStorageInterface $storage) {
-    parent::preSave($storage);
+  public static function preCreate(EntityStorageInterface $storage, array &$values) {
+    parent::preCreate($storage, $values);
 
-    $url = Url::createFromPath($this->path->value);
-    $this->setRouteName($url->getRouteName());
-    $this->setRouteParams($url->getRouteParameters());
+    if (!isset($values['shortcut_set'])) {
+      $values['shortcut_set'] = 'default';
+    }
   }
 
   /**
@@ -171,13 +166,22 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setLabel(t('Weight'))
       ->setDescription(t('Weight among shortcuts in the same shortcut set.'));
 
-    $fields['route_name'] = FieldDefinition::create('string')
-      ->setLabel(t('Route name'))
-      ->setDescription(t('The machine name of a defined Route this shortcut represents.'));
-
-    $fields['route_parameters'] = FieldDefinition::create('map')
-      ->setLabel(t('Route parameters'))
-      ->setDescription(t('A serialized array of route parameters of this shortcut.'));
+    $fields['link'] = FieldDefinition::create('link')
+      ->setLabel(t('Path'))
+      ->setDescription(t('The location this shortcut points to.'))
+      ->setRequired(TRUE)
+      ->setTranslatable(FALSE)
+      ->setSettings(array(
+        'default_value' => '',
+        'max_length' => 560,
+        'link_type' => LinkItemInterface::LINK_INTERNAL,
+        'title' => DRUPAL_DISABLED,
+      ))
+      ->setDisplayOptions('form', array(
+        'type' => 'link',
+        'weight' => 0,
+      ))
+      ->setDisplayConfigurable('form', TRUE);
 
     $fields['langcode'] = FieldDefinition::create('language')
       ->setLabel(t('Language code'))
@@ -187,15 +191,6 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setLabel(t('Default language'))
       ->setDescription(t('Flag to indicate whether this is the default language.'));
 
-    $fields['path'] = FieldDefinition::create('string')
-      ->setLabel(t('Path'))
-      ->setDescription(t('The computed shortcut path.'))
-      ->setComputed(TRUE);
-
-    $item_definition = $fields['path']->getItemDefinition();
-    $item_definition->setClass('\Drupal\shortcut\ShortcutPathItem');
-    $fields['path']->setItemDefinition($item_definition);
-
     return $fields;
   }
 
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php b/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php
index 0d427be..216d5d7 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Form/SetCustomize.php
@@ -51,7 +51,10 @@ public function form(array $form, array &$form_state) {
     foreach ($this->entity->getShortcuts() as $shortcut) {
       $id = $shortcut->id();
       $form['shortcuts']['links'][$id]['#attributes']['class'][] = 'draggable';
-      $form['shortcuts']['links'][$id]['name']['#markup'] = l($shortcut->getTitle(), $shortcut->path->value);
+      $form['shortcuts']['links'][$id]['name'] = array(
+        '#type' => 'link',
+        '#title' => $shortcut->getTitle(),
+      ) + $shortcut->getUrl()->toRenderArray();
       $form['shortcuts']['links'][$id]['#weight'] = $shortcut->getWeight();
       $form['shortcuts']['links'][$id]['weight'] = array(
         '#type' => 'weight',
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Form/ShortcutDeleteForm.php b/core/modules/shortcut/lib/Drupal/shortcut/Form/ShortcutDeleteForm.php
index b5bbabe..d0f67b3 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Form/ShortcutDeleteForm.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Form/ShortcutDeleteForm.php
@@ -25,7 +25,7 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function getQuestion() {
-    return $this->t('Are you sure you want to delete the shortcut %title?', array('%title' => $this->entity->title->value));
+    return $this->t('Are you sure you want to delete the shortcut %title?', array('%title' => $this->entity->getTitle()));
   }
 
   /**
@@ -58,7 +58,7 @@ public function submit(array $form, array &$form_state) {
         'shortcut_set' => $this->entity->bundle(),
       ),
     );
-    drupal_set_message($this->t('The shortcut %title has been deleted.', array('%title' => $this->entity->title->value)));
+    drupal_set_message($this->t('The shortcut %title has been deleted.', array('%title' => $this->entity->getTitle())));
   }
 
 }
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php
index c34f876..9afc8fb 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutFormController.php
@@ -28,15 +28,6 @@ class ShortcutFormController extends ContentEntityFormController {
   public function form(array $form, array &$form_state) {
     $form = parent::form($form, $form_state);
 
-    $form['path'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Path'),
-      '#size' => 40,
-      '#maxlength' => 255,
-      '#field_prefix' => $this->url('<front>', array(), array('absolute' => TRUE)),
-      '#default_value' => $this->entity->path->value,
-    );
-
     $form['langcode'] = array(
       '#title' => t('Language'),
       '#type' => 'language_select',
@@ -48,30 +39,6 @@ public function form(array $form, array &$form_state) {
   }
 
   /**
-   * Overrides EntityFormController::buildEntity().
-   */
-  public function buildEntity(array $form, array &$form_state) {
-    $entity = parent::buildEntity($form, $form_state);
-
-    // Set the computed 'path' value so it can used in the preSave() method to
-    // derive the route name and parameters.
-    $entity->path->value = $form_state['values']['path'];
-
-    return $entity;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validate(array $form, array &$form_state) {
-    if (!shortcut_valid_link($form_state['values']['path'])) {
-      $this->setFormError('path', $form_state, $this->t('The shortcut must correspond to a valid path on the site.'));
-    }
-
-    parent::validate($form, $form_state);
-  }
-
-  /**
    * {@inheritdoc}
    */
   public function save(array $form, array &$form_state) {
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutInterface.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutInterface.php
index 9a6bb98..2449131 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutInterface.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutInterface.php
@@ -90,4 +90,12 @@ public function getRouteParams();
   */
   public function setRouteParams($route_parameters);
 
+  /**
+   * Returns the Url object for the link this shortcut points to.
+   *
+   * @return \Drupal\Core\Url
+   *   The Url object.
+   */
+  public function getUrl();
+
 }
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutPathValue.php b/core/modules/shortcut/lib/Drupal/shortcut/ShortcutPathValue.php
deleted file mode 100644
index 2c8b4e5..0000000
--- a/core/modules/shortcut/lib/Drupal/shortcut/ShortcutPathValue.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\shortcut\ShortcutPathValue.
- */
-
-namespace Drupal\shortcut;
-
-use Drupal\Core\TypedData\TypedData;
-
-/**
- * A computed property for the string value of the path field.
- */
-class ShortcutPathValue extends TypedData {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getValue() {
-    if (!isset($this->value)) {
-      if (!isset($this->parent)) {
-        throw new \InvalidArgumentException('Computed properties require context for computation.');
-      }
-
-      $entity = $this->parent->getEntity();
-      if ($route_name = $entity->getRouteName()) {
-        $path = \Drupal::urlGenerator()->getPathFromRoute($route_name, $entity->getRouteParams());
-        $this->value = trim($path, '/');
-      }
-      else {
-        $this->value = NULL;
-      }
-    }
-    return $this->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setValue($value, $notify = TRUE) {
-    // Normalize the path in case it is an alias.
-    $value = \Drupal::service('path.alias_manager')->getSystemPath($value);
-    if (empty($value)) {
-      $value = '<front>';
-    }
-
-    parent::setValue($value, $notify);
-  }
-
-}
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php
index 67f40ad..840ca66 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutLinksTest.php
@@ -42,7 +42,7 @@ public function testShortcutLinkAdd() {
 
     // Create some paths to test.
     $test_cases = array(
-      array('path' => ''),
+      array('path' => '<front>'),
       array('path' => 'admin'),
       array('path' => 'admin/config/system/site-information'),
       array('path' => 'node/' . $this->node->id() . '/edit'),
@@ -56,13 +56,13 @@ public function testShortcutLinkAdd() {
       $title = $this->randomName();
       $form_data = array(
         'title[0][value]' => $title,
-        'path' => $test['path'],
+        'link[0][url]' => $test['path'],
       );
       $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save'));
       $this->assertResponse(200);
       $saved_set = shortcut_set_load($set->id());
-      $paths = $this->getShortcutInformation($saved_set, 'path');
-      $this->assertTrue(in_array($this->container->get('path.alias_manager')->getSystemPath($test['path']), $paths), 'Shortcut created: ' . $test['path']);
+      $paths = $this->getShortcutInformation($saved_set, 'link');
+      $this->assertTrue(in_array($test['path'], $paths), 'Shortcut created: ' . $test['path']);
       $this->assertLink($title, 0, 'Shortcut link found on the page.');
     }
   }
@@ -109,7 +109,7 @@ public function testShortcutLinkRename() {
 
     $shortcuts = $set->getShortcuts();
     $shortcut = reset($shortcuts);
-    $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $new_link_name, 'path' => $shortcut->path->value), t('Save'));
+    $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $new_link_name, 'link[0][url]' => $shortcut->link->url), t('Save'));
     $saved_set = shortcut_set_load($set->id());
     $titles = $this->getShortcutInformation($saved_set, 'title');
     $this->assertTrue(in_array($new_link_name, $titles), 'Shortcut renamed: ' . $new_link_name);
@@ -127,9 +127,9 @@ public function testShortcutLinkChangePath() {
 
     $shortcuts = $set->getShortcuts();
     $shortcut = reset($shortcuts);
-    $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $shortcut->getTitle(), 'path' => $new_link_path), t('Save'));
+    $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $shortcut->getTitle(), 'link[0][url]' => $new_link_path), t('Save'));
     $saved_set = shortcut_set_load($set->id());
-    $paths = $this->getShortcutInformation($saved_set, 'path');
+    $paths = $this->getShortcutInformation($saved_set, 'link');
     $this->assertTrue(in_array($new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
     $this->assertLinkByHref($new_link_path, 0, 'Shortcut with new path appears on the page.');
   }
diff --git a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php
index de9e110..70b5170 100644
--- a/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php
+++ b/core/modules/shortcut/lib/Drupal/shortcut/Tests/ShortcutTestBase.php
@@ -57,7 +57,10 @@ function setUp() {
         'set' => 'default',
         'title' => t('Add content'),
         'weight' => -20,
-        'path' => 'node/add',
+        'link' => array(
+          'url' => 'node/add',
+          'route_name' => 'node.add_page',
+        ),
       ));
       $shortcut->save();
 
@@ -65,7 +68,10 @@ function setUp() {
         'set' => 'default',
         'title' => t('All content'),
         'weight' => -19,
-        'path' => 'admin/content',
+        'link' => array(
+          'url' => 'admin/content',
+          'route_name' => 'node.content_overview',
+        ),
       ));
       $shortcut->save();
     }
@@ -113,7 +119,8 @@ function getShortcutInformation(ShortcutSetInterface $set, $key) {
     $info = array();
     \Drupal::entityManager()->getStorage('shortcut')->resetCache();
     foreach ($set->getShortcuts() as $shortcut) {
-      $info[] = $shortcut->{$key}->value;
+      $main_property_name = $shortcut->{$key}->getFieldDefinition()->getMainPropertyName();
+      $info[] = $shortcut->{$key}->{$main_property_name};
     }
     return $info;
   }
diff --git a/core/modules/shortcut/shortcut.info.yml b/core/modules/shortcut/shortcut.info.yml
index dde0e9c..8293685 100644
--- a/core/modules/shortcut/shortcut.info.yml
+++ b/core/modules/shortcut/shortcut.info.yml
@@ -5,3 +5,5 @@ package: Core
 version: VERSION
 core: 8.x
 configure: shortcut.set_admin
+dependencies:
+  - link
diff --git a/core/modules/shortcut/shortcut.install b/core/modules/shortcut/shortcut.install
index b7ed49c..4cb850d 100644
--- a/core/modules/shortcut/shortcut.install
+++ b/core/modules/shortcut/shortcut.install
@@ -5,9 +5,6 @@
  * Install, update and uninstall functions for the shortcut module.
  */
 
-use Drupal\Core\Database\Database;
-use Drupal\Core\Language\Language;
-
 /**
  * Implements hook_schema().
  */
@@ -46,13 +43,27 @@ function shortcut_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
-      'route_name' => array(
-        'description' => 'The machine name of a defined Symfony Route this menu item represents.',
+      'link__url' => array(
+        'description' => 'The URL of the link.',
+        'type' => 'varchar',
+        'length' => 2048,
+        'not null' => FALSE,
+      ),
+      'link__route_name' => array(
+        'description' => 'The machine name of a defined Route this link represents.',
         'type' => 'varchar',
         'length' => 255,
+        'not null' => FALSE,
+      ),
+      'link__route_parameters' => array(
+        'description' => 'Serialized array of route parameters of the link.',
+        'type' => 'blob',
+        'size' => 'big',
+        'not null' => FALSE,
+        'serialize' => TRUE,
       ),
-      'route_parameters' => array(
-        'description' => 'Serialized array of route parameters of this shortcut.',
+      'link__options' => array(
+        'description' => 'Serialized array of options for the link.',
         'type' => 'blob',
         'size' => 'big',
         'not null' => FALSE,
diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module
index 870bd8a..0d33bf0 100644
--- a/core/modules/shortcut/shortcut.module
+++ b/core/modules/shortcut/shortcut.module
@@ -301,10 +301,10 @@ function shortcut_renderable_links($shortcut_set = NULL) {
 
   $shortcuts = \Drupal::entityManager()->getStorage('shortcut')->loadByProperties(array('shortcut_set' => $shortcut_set->id()));
   foreach ($shortcuts as $shortcut) {
-    $links[] = array(
-      'title' => $shortcut->label(),
-      'href' => $shortcut->path->value,
-    );
+    $links[$shortcut->id()] = array(
+      'type' => 'link',
+      'title' => $shortcut->getTitle(),
+    ) + $shortcut->getUrl()->toArray();
   }
 
   if (!empty($links)) {
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index 60c6f72..f5b6c97 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -65,7 +65,10 @@ function standard_install() {
     'shortcut_set' => 'default',
     'title' => t('Add content'),
     'weight' => -20,
-    'path' => 'node/add',
+    'link' => array(
+      'url' => 'node/add',
+      'route_name' => 'node.add_page',
+    ),
   ));
   $shortcut->save();
 
@@ -73,7 +76,10 @@ function standard_install() {
     'shortcut_set' => 'default',
     'title' => t('All content'),
     'weight' => -19,
-    'path' => 'admin/content',
+    'link' => array(
+      'url' => 'admin/content',
+      'route_name' => 'node.content_overview',
+    ),
   ));
   $shortcut->save();
 
diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php
index a2a7ec0..1b0c582 100644
--- a/core/tests/Drupal/Tests/Core/UrlTest.php
+++ b/core/tests/Drupal/Tests/Core/UrlTest.php
@@ -34,6 +34,13 @@ class UrlTest extends UnitTestCase {
   protected $urlGenerator;
 
   /**
+   * The path alias manager.
+   *
+   * @var \Drupal\Core\Path\AliasManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $pathAliasManager;
+
+  /**
    * The router.
    *
    * @var \Drupal\Tests\Core\Routing\TestRouterInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -70,15 +77,31 @@ protected function setUp() {
     $map[] = array('node_edit', array('node' => '2'), array(), '/node/2/edit');
     $this->map = $map;
 
+    $alias_map = array(
+      // Set up one proper alias that can be resolved to a system path.
+      array('node-alias-test', NULL, 'node'),
+      // Passing in anything else should return the same string.
+      array('node', NULL, 'node'),
+      array('node/1', NULL, 'node/1'),
+      array('node/2/edit', NULL, 'node/2/edit'),
+      array('non-existent', NULL, 'non-existent'),
+    );
+
     $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
     $this->urlGenerator->expects($this->any())
       ->method('generateFromRoute')
       ->will($this->returnValueMap($this->map));
 
+    $this->pathAliasManager = $this->getMock('Drupal\Core\Path\AliasManagerInterface');
+    $this->pathAliasManager->expects($this->any())
+      ->method('getSystemPath')
+      ->will($this->returnValueMap($alias_map));
+
     $this->router = $this->getMock('Drupal\Tests\Core\Routing\TestRouterInterface');
     $container = new ContainerBuilder();
     $container->set('router', $this->router);
     $container->set('url_generator', $this->urlGenerator);
+    $container->set('path.alias_manager.cached', $this->pathAliasManager);
     \Drupal::setContainer($container);
   }
 
@@ -126,6 +149,27 @@ public function testCreateFromPathFront() {
   }
 
   /**
+   * Tests the createFromPath method with a path alias.
+   *
+   * @covers ::createFromPath()
+   */
+  public function testCreateFromPathAlias() {
+    $this->router->expects($this->any())
+      ->method('match')
+      ->will($this->returnValueMap(array(
+        array('/node', array(
+          RouteObjectInterface::ROUTE_NAME => 'view.frontpage.page_1',
+          '_raw_variables' => new ParameterBag(),
+        )),
+      )));
+
+    $values = $this->map[0];
+    array_pop($values);
+    $url = Url::createFromPath('node-alias-test');
+    $this->assertSame($values, array_values($url->toArray()));
+  }
+
+  /**
    * Tests that an invalid path will thrown an exception.
    *
    * @covers ::createFromPath()
