diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 6e0b4d8..931d5ec 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Link;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\TypedData\TranslatableInterface;
 use Drupal\Core\Url;
 
 /**
@@ -310,6 +311,28 @@ protected function urlRouteParameters($rel) {
       $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
     }
 
+    // @todo Remove this after https://www.drupal.org/node/2113345
+    elseif ($rel === 'drupal:content-translation-add' && $this instanceof TranslatableInterface) {
+      $possible_sources = [];
+      $possible_targets = [];
+      foreach ($this->languageManager()->getLanguages() as $langcode => $language) {
+        if ($this->hasTranslation($langcode)) {
+          $possible_sources[] = $langcode;
+        }
+        else {
+          $possible_targets[] = $langcode;
+        }
+        // If there is no possible source or target language, set the
+        // corresponding route parameter to any language to avoid exceptions in
+        // the URL generation.
+        $uri_route_parameters['source'] = $possible_sources ? reset($possible_sources) : $this->language()->getId();
+        $uri_route_parameters['target'] = $possible_targets ? reset($possible_targets) : $this->language()->getId();
+      }
+    }
+    elseif (in_array($rel, ['drupal:content-translation-edit', 'drupal:content-translation-delete'], TRUE) && $this instanceof TranslatableInterface) {
+      $uri_route_parameters['language'] = $this->language()->getId();
+    }
+
     return $uri_route_parameters;
   }
 
diff --git a/core/modules/content_translation/src/Access/ContentTranslationManageAccessCheck.php b/core/modules/content_translation/src/Access/ContentTranslationManageAccessCheck.php
index 6a4be1e..3360b19 100644
--- a/core/modules/content_translation/src/Access/ContentTranslationManageAccessCheck.php
+++ b/core/modules/content_translation/src/Access/ContentTranslationManageAccessCheck.php
@@ -93,6 +93,9 @@ public function access(Route $route, RouteMatchInterface $route_match, AccountIn
       /* @var \Drupal\content_translation\ContentTranslationHandlerInterface $handler */
       $handler = $this->entityManager->getHandler($entity->getEntityTypeId(), 'translation');
 
+      // Reload unchanged entity to get stored translation only.
+      $entity = $this->entityManager->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
+
       // Load translation.
       $translations = $entity->getTranslationLanguages();
       $languages = $this->languageManager->getLanguages();
diff --git a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
index fb4b761..1dfe592 100644
--- a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
@@ -82,8 +82,6 @@ protected function alterRoutes(RouteCollection $collection) {
         $path . '/add/{source}/{target}',
         array(
           '_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::add',
-          'source' => NULL,
-          'target' => NULL,
           '_title' => 'Add',
           'entity_type_id' => $entity_type_id,
 
@@ -113,7 +111,6 @@ protected function alterRoutes(RouteCollection $collection) {
         $path . '/edit/{language}',
         array(
           '_controller' => '\Drupal\content_translation\Controller\ContentTranslationController::edit',
-          'language' => NULL,
           '_title' => 'Edit',
           'entity_type_id' => $entity_type_id,
         ),
@@ -138,7 +135,6 @@ protected function alterRoutes(RouteCollection $collection) {
         $path . '/delete/{language}',
         array(
           '_entity_form' => $entity_type_id . '.content_translation_deletion',
-          'language' => NULL,
           '_title' => 'Delete',
           'entity_type_id' => $entity_type_id,
         ),
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
index e9fff8d..2136b74 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
@@ -108,6 +108,21 @@ protected function doTestBasicTranslation() {
       'source' => $default_langcode,
       'target' => $langcode
     ], array('language' => $language));
+
+    // Ensure that there are not 'Add' breadcrumbs.
+    $url_string = $add_url->toString();
+    $this->drupalGet($url_string);
+    $links = $this->xpath('//nav[@class="breadcrumb"]/ol/li/a[text()="Add"]');
+    $this->assert(empty($links), 'No "Add" breadcrumbs.');
+
+    // Ensure that removing the last two url parts does not yield a fatal error.
+    $url_parts = explode('/', $url_string);
+    for ($i = 0; $i < 2; $i++) {
+      array_pop($url_parts);
+      $this->drupalGet(implode('/', $url_parts));
+      $this->assertResponse(404);
+    }
+
     $this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), $this->getFormSubmitActionForNewTranslation($entity, $langcode));
 
     // Assert that HTML is escaped in "all languages" in UI after SafeMarkup
diff --git a/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php b/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
index 7390c0e..d073c1b 100644
--- a/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
+++ b/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
@@ -54,11 +54,49 @@ public function testCreateAccess() {
       ->method('getTranslationAccess')
       ->will($this->returnValue(AccessResult::allowed()));
 
+    // Set the mock entity. We need to use ContentEntityBase for mocking due to
+    // issues with phpunit and multiple interfaces.
+    $entity = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $entity->expects($this->exactly(2))
+      ->method('getEntityTypeId')
+      ->willReturn('node');
+    $entity->expects($this->once())
+      ->method('getTranslationLanguages')
+      ->with()
+      ->will($this->returnValue(array()));
+    $entity->expects($this->once())
+      ->method('getCacheContexts')
+      ->willReturn([]);
+    $entity->expects($this->once())
+      ->method('getCacheMaxAge')
+      ->willReturn(Cache::PERMANENT);
+    $entity->expects($this->once())
+      ->method('getCacheTags')
+      ->will($this->returnValue(array('node:1337')));
+    $entity->expects($this->once())
+      ->method('getCacheContexts')
+      ->willReturn(array());
+    $entity->expects($this->once())
+      ->method('id')
+      ->willReturn(1337);
+
+    $entity_storage = $this->getMock('\Drupal\Core\Entity\EntityStorageInterface');
+    $entity_storage->expects($this->once())
+      ->method('loadUnchanged')
+      ->with(1337)
+      ->willReturn($entity);
+
     $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
     $entity_manager->expects($this->once())
       ->method('getHandler')
       ->withAnyParameters()
       ->will($this->returnValue($translation_handler));
+    $entity_manager->expects($this->once())
+      ->method('getStorage')
+      ->with('node')
+      ->willReturn($entity_storage);
 
     // Set our source and target languages.
     $source = 'en';
@@ -82,30 +120,6 @@ public function testCreateAccess() {
       ->with($this->equalTo($target))
       ->will($this->returnValue(new Language(array('id' => 'it'))));
 
-    // Set the mock entity. We need to use ContentEntityBase for mocking due to
-    // issues with phpunit and multiple interfaces.
-    $entity = $this->getMockBuilder('Drupal\Core\Entity\ContentEntityBase')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $entity->expects($this->once())
-      ->method('getEntityTypeId');
-    $entity->expects($this->once())
-      ->method('getTranslationLanguages')
-      ->with()
-      ->will($this->returnValue(array()));
-    $entity->expects($this->once())
-      ->method('getCacheContexts')
-      ->willReturn([]);
-    $entity->expects($this->once())
-      ->method('getCacheMaxAge')
-      ->willReturn(Cache::PERMANENT);
-    $entity->expects($this->once())
-      ->method('getCacheTags')
-      ->will($this->returnValue(array('node:1337')));
-    $entity->expects($this->once())
-      ->method('getCacheContexts')
-      ->willReturn(array());
-
     // Set the route requirements.
     $route = new Route('test_route');
     $route->setRequirement('_access_content_translation_manage', 'create');
