diff --git a/app/assets/javascripts/blob/notebook_viewer.js b/app/assets/javascripts/blob/notebook_viewer.js
index dda137c6603792efd1def89e70d424097807c94c..057afc9b2e5aa3ff11acf13d0e37f0c7b24436c7 100644
--- a/app/assets/javascripts/blob/notebook_viewer.js
+++ b/app/assets/javascripts/blob/notebook_viewer.js
@@ -1,20 +1,49 @@
 import Vue from 'vue';
+import VueResource from 'vue-resource';
 import NotebookLab from 'vendor/notebooklab';
 
+Vue.use(VueResource);
 Vue.use(NotebookLab);
 
 $(() => {
+  const el = document.getElementById('js-notebook-viewer');
+
   new Vue({
-    el: '#js-notebook-viewer',
+    el,
     data() {
       return {
+        loading: true,
         json: {},
       };
     },
     template: `
-      <div>
-        <notebook-lab :notebook="json" />
+      <div class="container-fluid">
+        <i
+          class="fa fa-spinner fa-spin"
+          v-if="loading">
+        </i>
+        <notebook-lab
+          v-if="!loading"
+          :notebook="json" />
       </div>
     `,
+    mounted() {
+      $.get(gon.katex_css_url, () => {
+        const css = $('<link>', {
+          rel: 'stylesheet',
+          type: 'text/css',
+          href: gon.katex_css_url,
+        });
+        css.appendTo('head');
+      });
+
+      $.getScript(gon.katex_js_url, () => {
+        this.$http.get(el.dataset.endpoint)
+          .then((res) => {
+            this.json = res.json();
+            this.loading = false;
+          });
+      });
+    },
   });
 });
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 83a8eeaafdeda103e5e184f9f0fb771eae0670bc..0a4c69bc5ac940dfe8b44e926a0551f5dc253ef6 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -7,6 +7,7 @@
  *= require_self
  *= require dropzone/basic
  *= require cropper.css
+ *= require notebooklab.css
 */
 
 /*
diff --git a/app/views/projects/blob/_notebook.html.haml b/app/views/projects/blob/_notebook.html.haml
index 19d3e401d27f236a0d768c7666eb9a6735a21582..ab1cf933944128e5d6fae47f5160a330622b09e6 100644
--- a/app/views/projects/blob/_notebook.html.haml
+++ b/app/views/projects/blob/_notebook.html.haml
@@ -2,4 +2,4 @@
   = page_specific_javascript_bundle_tag('common_vue')
   = page_specific_javascript_bundle_tag('notebook_viewer')
 
-.file-content#js-notebook-viewer
+.file-content#js-notebook-viewer{ data: { endpoint: namespace_project_raw_path(@project.namespace, @project, @id) } }
diff --git a/vendor/assets/stylesheets/notebooklab.css b/vendor/assets/stylesheets/notebooklab.css
new file mode 100644
index 0000000000000000000000000000000000000000..0caf729a17f98e87fd518783f2f0619ffee9d48e
--- /dev/null
+++ b/vendor/assets/stylesheets/notebooklab.css
@@ -0,0 +1,27 @@
+.cell,
+.input,
+.output {
+  display: flex;
+  width: 100%;
+  margin-bottom: 10px;
+}
+
+.cell:not(.text-cell) {
+  flex-direction: column;
+}
+
+.prompt {
+  padding: 0 10px;
+  min-width: 7em;
+  font-family: monospace;
+}
+
+.cell pre {
+  margin: 0;
+  width: 100%;
+}
+
+.markdown .katex {
+  display: block;
+  text-align: center;
+}