diff --git a/core/modules/views/src/Form/ViewsForm.php b/core/modules/views/src/Form/ViewsForm.php
index cdf39eb..4951777 100644
--- a/core/modules/views/src/Form/ViewsForm.php
+++ b/core/modules/views/src/Form/ViewsForm.php
@@ -14,6 +14,7 @@
 use Drupal\Core\Form\FormInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\UrlGeneratorInterface;
+use Drupal\Core\Url;
 use Drupal\views\ViewExecutable;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\RequestStack;
diff --git a/core/modules/views/src/Tests/PreviewTest.php b/core/modules/views/src/Tests/PreviewTest.php
new file mode 100644
index 0000000..7ad14ee
--- /dev/null
+++ b/core/modules/views/src/Tests/PreviewTest.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains of \Drupal\views\Tests\PreviewTest.
+ */
+
+namespace Drupal\views\Tests;
+
+use Drupal\views\Views;
+
+/**
+ * Tests covering Preview functionality in Views.
+ *
+ * @group views
+ */
+class PreviewTest extends ViewTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node', 'views_ui'];
+
+  /**
+    * Views used by this test.
+    *
+    * @var array
+    */
+  public static $testViews = ['content'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+  }
+
+  /**
+   * Tests previews of unsaved new page displays.
+   */
+  public function testUsavedPageDisplayPreview() {
+    $this->drupalCreateContentType(['type' => 'page']);
+    for ($i = 0; $i < 5; $i++) {
+      $this->drupalCreateNode();
+    }
+
+    $admin_user = $this->drupalCreateUser(['administer views', 'administer site configuration']);
+    $this->drupalLogin($admin_user);
+
+    $this->drupalGet('admin/structure/views/view/content');
+    $this->assertResponse(200);
+
+    $this->drupalPostForm(NULL, [], t('Add Page'));
+    $this->assertResponse(200);
+
+    $this->drupalGet('admin/structure/views/nojs/display/content/page_2/path');
+    $this->assertResponse(200);
+
+    $this->drupalPostForm(NULL, ['path' => 'foo'], t('Apply'));
+    $this->assertResponse(200);
+
+    $this->drupalPostForm(NULL, [], t('Update preview'));
+    $this->assertResponse(200);
+  }
+
+}
diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php
index 11dce89..949a860 100644
--- a/core/modules/views/src/ViewExecutable.php
+++ b/core/modules/views/src/ViewExecutable.php
@@ -436,6 +436,23 @@ class ViewExecutable implements \Serializable {
   protected $routeProvider;
 
   /**
+   * If the view is currently being used for a live preview from the UI.
+   *
+   * @var bool
+   */
+  public $live_preview = FALSE;
+
+  /**
+   * If the view has been changed.
+   *
+   * @todo It is unclear whether this is actually used, both within the class
+   *   and outside.
+   *
+   * @var bool
+   */
+  public $changed = FALSE;
+
+  /**
    * Constructs a new ViewExecutable object.
    *
    * @param \Drupal\views\ViewEntityInterface $storage
@@ -1755,6 +1772,14 @@ public function hasUrl($args = NULL, $display_id = NULL) {
       return TRUE;
     }
 
+    if (!empty($this->live_preview)) {
+      return FALSE;
+    }
+
+    if (!empty($this->changed)) {
+      return FALSE;
+    }
+
     // If the display has a valid route available (either its own or for a
     // linked display), then we can provide a URL for it.
     $display_handler = $this->displayHandlers->get($display_id ?: $this->current_display)->getRoutedDisplay();
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 5aeac87..89c00fb 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -598,7 +598,7 @@ public function renderPreview($display_id, $args = array()) {
       $executable->setArguments($args);
 
       // Store the current view URL for later use:
-      if ($executable->display_handler->getOption('path')) {
+      if ($executable->hasUrl() && $executable->display_handler->getOption('path')) {
         $path = $executable->getUrl();
       }
 
