This repository has been archived by the owner on Dec 30, 2022. It is now read-only.
/
main.js
129 lines (113 loc) 路 3.4 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import Vue from 'vue';
import App from './App.vue';
import { createRouter } from './router';
import { createServerRootMixin } from 'vue-instantsearch';
import algoliasearch from 'algoliasearch/lite';
import qs from 'qs';
import _renderToString from 'vue-server-renderer/basic';
function renderToString(app) {
return new Promise((resolve, reject) => {
_renderToString(app, (err, res) => {
if (err) reject(err);
resolve(res);
});
});
}
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
Vue.config.productionTip = false;
export async function createApp({
beforeApp = () => {},
afterApp = () => {},
context,
} = {}) {
const router = createRouter();
await beforeApp({
router,
});
const app = new Vue({
mixins: [
createServerRootMixin({
searchClient,
indexName: 'instant_search',
routing: {
router: {
read() {
const url = context
? context.url
: typeof window.location === 'object'
? window.location.href
: '';
const search = url.slice(url.indexOf('?'));
return qs.parse(search, {
ignoreQueryPrefix: true,
});
},
write(routeState) {
const query = qs.stringify(routeState, {
addQueryPrefix: true,
});
if (typeof history === 'object') {
history.pushState(routeState, null, query);
}
},
createURL(routeState) {
const query = qs.stringify(routeState, {
addQueryPrefix: true,
});
return query;
},
onUpdate(callback) {
if (typeof window !== 'object') {
return;
}
this._onPopState = event => {
if (this.writeTimer) {
window.clearTimeout(this.writeTimer);
this.writeTimer = undefined;
}
const routeState = event.state;
// At initial load, the state is read from the URL without update.
// Therefore the state object is not available.
// In this case, we fallback and read the URL.
if (!routeState) {
callback(this.read());
} else {
callback(routeState);
}
};
window.addEventListener('popstate', this._onPopState);
},
dispose() {
if (this._onPopState && typeof window == 'object') {
window.removeEventListener('popstate', this._onPopState);
}
// we purposely don't write on dispose, to prevent double entries on navigation
},
},
},
// other options, like
// stalledSearchDelay: 50
}),
],
serverPrefetch() {
return this.instantsearch.findResultsState({ component: this, renderToString });
},
beforeMount() {
if (typeof window === 'object' && window.__ALGOLIA_STATE__) {
this.instantsearch.hydrate(window.__ALGOLIA_STATE__);
delete window.__ALGOLIA_STATE__;
}
},
router,
render: h => h(App),
});
const result = {
app,
router,
};
await afterApp(result);
return result;
}