Skip to content

Commit 4cb5724

Browse files
committed
fix: also set ssrAppId for first Vue app when ssrAttribute exists
1 parent 2792f0f commit 4cb5724

File tree

2 files changed

+54
-36
lines changed

2 files changed

+54
-36
lines changed

examples/ssr/App.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@ export default function createApp () {
6666
]
6767
})
6868

69-
const app = new Vue({
70-
router,
69+
const App = ({
7170
metaInfo () {
7271
return {
7372
title: 'Boring Title',
@@ -157,6 +156,11 @@ export default function createApp () {
157156
</div>`
158157
})
159158

159+
const app = new Vue({
160+
router,
161+
render: h => h(App)
162+
})
163+
160164
const { set } = app.$meta().addApp('custom')
161165
set({
162166
bodyAttrs: { class: 'custom-app' },

src/shared/mixin.js

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { triggerUpdate } from '../client/update'
22
import { isUndefined, isFunction } from '../utils/is-type'
33
import { find } from '../utils/array'
4+
import { getTag } from '../utils/elements'
45
import { rootConfigKey } from './constants'
56
import { hasMetaInfo } from './meta-helpers'
67
import { addNavGuards } from './nav-guards'
@@ -21,12 +22,6 @@ export default function createMixin (Vue, options) {
2122
const $options = this.$options
2223
const devtoolsEnabled = Vue.config.devtools
2324

24-
if (this === $root) {
25-
this.$on('hook:beforeMount', function () {
26-
wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered')
27-
})
28-
}
29-
3025
Object.defineProperty(this, '_hasMetaInfo', {
3126
configurable: true,
3227
get () {
@@ -39,6 +34,22 @@ export default function createMixin (Vue, options) {
3934
}
4035
})
4136

37+
if (this === $root) {
38+
$root.$once('hook:beforeMount', function () {
39+
wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered')
40+
41+
// In most cases when you have a SSR app it will be the first app thats gonna be
42+
// initiated, if we cant detect the data-server-rendered attribute from Vue but we
43+
// do see our own ssrAttribute then _assume_ the Vue app with appId 1 is the ssr app
44+
// attempted fix for #404 & #562, but we rly need to refactor how we pass appIds from
45+
// ssr to the client
46+
if (!wasServerRendered && $root[rootConfigKey] && $root[rootConfigKey].appId === 1) {
47+
const htmlTag = getTag({}, 'html')
48+
wasServerRendered = htmlTag && htmlTag.hasAttribute(options.ssrAttribute)
49+
}
50+
})
51+
}
52+
4253
// Add a marker to know if it uses metaInfo
4354
// _vnode is used to know that it's attached to a real component
4455
// useful if we use some mixin to add some meta tags (like nuxt-i18n)
@@ -107,6 +118,7 @@ export default function createMixin (Vue, options) {
107118

108119
this.$on('hook:beforeMount', function () {
109120
const $root = this[rootKey]
121+
110122
// if this Vue-app was server rendered, set the appId to 'ssr'
111123
// only one SSR app per page is supported
112124
if (wasServerRendered) {
@@ -119,35 +131,37 @@ export default function createMixin (Vue, options) {
119131
this.$on('hook:mounted', function () {
120132
const $root = this[rootKey]
121133

122-
if (!$root[rootConfigKey].initialized) {
123-
// used in triggerUpdate to check if a change was triggered
124-
// during initialization
125-
$root[rootConfigKey].initializing = true
126-
127-
// refresh meta in nextTick so all child components have loaded
128-
this.$nextTick(function () {
129-
const { tags, metaInfo } = $root.$meta().refresh()
130-
131-
// After ssr hydration (identifier by tags === false) check
132-
// if initialized was set to null in triggerUpdate. That'd mean
133-
// that during initilazation changes where triggered which need
134-
// to be applied OR a metaInfo watcher was triggered before the
135-
// current hook was called
136-
// (during initialization all changes are blocked)
137-
if (tags === false && $root[rootConfigKey].initialized === null) {
138-
this.$nextTick(() => triggerUpdate(options, $root, 'init'))
139-
}
140-
141-
$root[rootConfigKey].initialized = true
142-
delete $root[rootConfigKey].initializing
143-
144-
// add the navigation guards if they havent been added yet
145-
// they are needed for the afterNavigation callback
146-
if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) {
147-
addNavGuards($root)
148-
}
149-
})
134+
if ($root[rootConfigKey].initialized) {
135+
return
150136
}
137+
138+
// used in triggerUpdate to check if a change was triggered
139+
// during initialization
140+
$root[rootConfigKey].initializing = true
141+
142+
// refresh meta in nextTick so all child components have loaded
143+
this.$nextTick(function () {
144+
const { tags, metaInfo } = $root.$meta().refresh()
145+
146+
// After ssr hydration (identifier by tags === false) check
147+
// if initialized was set to null in triggerUpdate. That'd mean
148+
// that during initilazation changes where triggered which need
149+
// to be applied OR a metaInfo watcher was triggered before the
150+
// current hook was called
151+
// (during initialization all changes are blocked)
152+
if (tags === false && $root[rootConfigKey].initialized === null) {
153+
this.$nextTick(() => triggerUpdate(options, $root, 'init'))
154+
}
155+
156+
$root[rootConfigKey].initialized = true
157+
delete $root[rootConfigKey].initializing
158+
159+
// add the navigation guards if they havent been added yet
160+
// they are needed for the afterNavigation callback
161+
if (!options.refreshOnceOnNavigation && metaInfo.afterNavigation) {
162+
addNavGuards($root)
163+
}
164+
})
151165
})
152166
// add the navigation guards if requested
153167
if (options.refreshOnceOnNavigation) {

0 commit comments

Comments
 (0)