diff --git a/examples/extend-app/README.md b/examples/extend-app/README.md new file mode 100644 index 0000000000..e1f3805bbe --- /dev/null +++ b/examples/extend-app/README.md @@ -0,0 +1,42 @@ +# Extending the main app + +> Nuxt.js allows you to extend the main application by adding a `pages/_app.vue` file + +## The default app + +The default source code of the main app is: +```html + +``` + +## The `pages/_app.vue` file + +### 🎬 [Example video](https://www.youtube.com/watch?v=wBhia7uBxDA) + +You have to make sure to add the `` and `` components when extending the app. + +It is important that the code you add stays inside ``. + +Example: +```html + +``` + +## Demo + + +```bash +npm install +npm start +``` + +Go to [http://localhost:3000](http://localhost:3000) and navigate trough the app. Notice how the logo at the top right stays between the pages, even on the error page: [http://localhost:3000/404](http://localhost:3000/404) diff --git a/examples/extend-app/package.json b/examples/extend-app/package.json new file mode 100644 index 0000000000..ce5d6af2a6 --- /dev/null +++ b/examples/extend-app/package.json @@ -0,0 +1,11 @@ +{ + "name": "nuxt-extend-app", + "dependencies": { + "nuxt": "latest" + }, + "scripts": { + "dev": "nuxt", + "build": "nuxt build", + "start": "nuxt start" + } +} diff --git a/examples/extend-app/pages/_app.vue b/examples/extend-app/pages/_app.vue new file mode 100644 index 0000000000..a07eda60e8 --- /dev/null +++ b/examples/extend-app/pages/_app.vue @@ -0,0 +1,15 @@ + + + diff --git a/examples/extend-app/pages/about.vue b/examples/extend-app/pages/about.vue new file mode 100644 index 0000000000..cb9849695c --- /dev/null +++ b/examples/extend-app/pages/about.vue @@ -0,0 +1,16 @@ + + + diff --git a/examples/extend-app/pages/index.vue b/examples/extend-app/pages/index.vue new file mode 100644 index 0000000000..14713d2a05 --- /dev/null +++ b/examples/extend-app/pages/index.vue @@ -0,0 +1,6 @@ + diff --git a/examples/extend-app/static/logo.png b/examples/extend-app/static/logo.png new file mode 100644 index 0000000000..9d716abf22 Binary files /dev/null and b/examples/extend-app/static/logo.png differ diff --git a/examples/head-elements/components/twitter-head-card.vue b/examples/head-elements/components/twitter-head-card.vue index a998a84620..54391ee10b 100644 --- a/examples/head-elements/components/twitter-head-card.vue +++ b/examples/head-elements/components/twitter-head-card.vue @@ -3,7 +3,7 @@ - -<% css.forEach(function (c) { %> - -<% }) %> diff --git a/lib/app/client.js b/lib/app/client.js index 47e24ef54f..3af45382ce 100644 --- a/lib/app/client.js +++ b/lib/app/client.js @@ -112,8 +112,9 @@ function render (to, ___, next) { // Special hot reload with data(context) function hotReloadAPI (_app) { - var _forceUpdate = _app.$forceUpdate.bind(_app) - _app.$forceUpdate = function () { + const $nuxt = _app.$nuxt + var _forceUpdate = $nuxt.$forceUpdate.bind($nuxt) + $nuxt.$forceUpdate = function () { let Component = getMatchedComponents(router.currentRoute)[0] if (!Component) return _forceUpdate() if (typeof Component === 'object' && !Component.options) { @@ -127,7 +128,7 @@ function hotReloadAPI (_app) { <%= (loading ? 'this.$loading.finish && this.$loading.finish()' : '') %> router.push(path) } - const context = getContext({ route: router.currentRoute<%= (store ? ', store' : '') %>, isClient: true, next: next.bind(this), error: _app.error.bind(_app) }) + const context = getContext({ route: router.currentRoute<%= (store ? ', store' : '') %>, isClient: true, next: next.bind(this), error: _app.error }) // Check if data has been updated const originalDataFn = (Component._data || noopData).toString().replace(/\s/g, '') const newDataFn = (Component._Ctor.options.data || noopData).toString().replace(/\s/g, '') @@ -206,17 +207,27 @@ const resolveComponents = flatMapComponents(router.match(path), (Component, _, m Promise.all(resolveComponents) .then((Components) => { const _app = new Vue(app) - const mountApp = () => _app.$mount('#__nuxt') - const onNuxtReady = window.onNuxtReady || function () {} + const mountApp = () => { + _app.$mount('#__nuxt') + <% if (loading) { %> + // Special loading bar + _app.$loading = _app.$nuxt.$loading + <% } %> + // Hot reloading + if (module.hot) hotReloadAPI(_app) + // Useful for jsdom testing or plugins (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading) + if (typeof window.onNuxtReady === 'function') { + window.onNuxtReady(_app) + } + } + _app.error = _app.$options._nuxt.error.bind(_app) + _app.$loading = {} // to avoid error while _app.$nuxt does not exist if (NUXT.error) _app.error(NUXT.error) - if (module.hot) hotReloadAPI(_app) // Add router hooks router.beforeEach(loadAsyncComponents.bind(_app)) router.beforeEach(render.bind(_app)) if (NUXT.serverRendered) { mountApp() - // Call window.onModulesLoaded for jsdom testing (https://github.com/tmpvar/jsdom#dealing-with-asynchronous-script-loading) - onNuxtReady(_app) return } render.call(_app, router.currentRoute, router.currentRoute, function (path) { @@ -226,13 +237,11 @@ Promise.all(resolveComponents) if (mounted) return mounted = true mountApp() - onNuxtReady(_app) }) router.push(path) return } mountApp() - onNuxtReady(_app) }) }) .catch((err) => { diff --git a/lib/app/components/nuxt-error-debug.vue b/lib/app/components/nuxt-error-debug.vue index 542d203636..d84133ef72 100755 --- a/lib/app/components/nuxt-error-debug.vue +++ b/lib/app/components/nuxt-error-debug.vue @@ -13,6 +13,7 @@