Skip to content

Commit c18bbce

Browse files
committed
Route docsearch to Vercel proxy and forward X-MS-USER-ID server-side
1 parent 6408d50 commit c18bbce

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

docusaurus/api/meili-search.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
export default async function handler(req, res) {
2+
if (req.method !== 'POST') {
3+
res.status(405).json({ error: 'Method Not Allowed' });
4+
return;
5+
}
6+
7+
try {
8+
const { indexUid } = req.query || {};
9+
if (!indexUid) {
10+
res.status(400).json({ error: 'Missing indexUid' });
11+
return;
12+
}
13+
14+
const host = process.env.MEILI_HOST || process.env.NEXT_PUBLIC_MEILI_HOST || '';
15+
const apiKey = process.env.MEILI_API_KEY || process.env.NEXT_PUBLIC_MEILI_API_KEY || '';
16+
if (!host || !apiKey) {
17+
res.status(500).json({ error: 'Meilisearch host or API key not configured' });
18+
return;
19+
}
20+
21+
const userIdFromCookie = (() => {
22+
try {
23+
const cookie = req.headers['cookie'] || '';
24+
const match = cookie.match(/(?:^|;\s*)msUserId=([^;]+)/);
25+
return match ? decodeURIComponent(match[1]) : undefined;
26+
} catch {
27+
return undefined;
28+
}
29+
})();
30+
31+
const url = new URL(`/indexes/${encodeURIComponent(indexUid)}/search`, host);
32+
const meiliRes = await fetch(url.toString(), {
33+
method: 'POST',
34+
headers: {
35+
'Content-Type': 'application/json',
36+
'Authorization': `Bearer ${apiKey}`,
37+
'X-Meilisearch-Client': req.headers['x-meilisearch-client'] || 'StrapiDocs Proxy',
38+
...(userIdFromCookie ? { 'X-MS-USER-ID': userIdFromCookie } : {}),
39+
},
40+
body: JSON.stringify(req.body || {}),
41+
});
42+
43+
const data = await meiliRes.json();
44+
res.status(meiliRes.status).json(data);
45+
} catch (e) {
46+
res.status(500).json({ error: e.message || 'Proxy error' });
47+
}
48+
}
49+

docusaurus/docusaurus.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ const config = {
130130
],
131131
customFields: {
132132
meilisearch: {
133-
host: 'https://ms-47f23e4f6fb9-30446.fra.meilisearch.io',
134-
apiKey: '45326fd7e6278ec3fc83af7a5c20a2ab4261f8591bd186adf8bf8f962581622b',
133+
host: process.env.NEXT_PUBLIC_MEILI_HOST || 'https://ms-47f23e4f6fb9-30446.fra.meilisearch.io',
134+
apiKey: process.env.NEXT_PUBLIC_MEILI_API_KEY || '45326fd7e6278ec3fc83af7a5c20a2ab4261f8591bd186adf8bf8f962581622b',
135135
indexUid: 'strapi-docs',
136136
searchParams: {
137137
attributesToHighlight: null

docusaurus/src/theme/SearchBar/index.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ function SearchBarContent() {
3939
const uuid = (typeof crypto !== 'undefined' && crypto.randomUUID) ? crypto.randomUUID() : Math.random().toString(36).slice(2) + Date.now().toString(36);
4040
const value = JSON.stringify({ id: uuid, month: monthKey });
4141
window.localStorage.setItem(key, value);
42+
try {
43+
// Also set a same‑origin cookie so serverless proxy can read it
44+
const ttlDays = 45; // longer than a month for safety; we rotate monthly client‑side
45+
const maxAge = ttlDays * 24 * 60 * 60;
46+
document.cookie = `msUserId=${uuid}; Max-Age=${maxAge}; Path=/; SameSite=Lax` + (window.location.protocol === 'https:' ? '; Secure' : '');
47+
} catch {}
4248
return uuid;
4349
} catch (_) {
4450
return null;
@@ -158,9 +164,12 @@ function SearchBarContent() {
158164
import('meilisearch-docsearch'),
159165
import('meilisearch-docsearch/css')
160166
]).then(([{ docsearch }]) => {
167+
const meiliHost = siteConfig.customFields.meilisearch.host;
168+
// Use proxy on non-localhost to avoid CORS limits and inject server-side header
169+
const useProxy = typeof window !== 'undefined' && window.location && window.location.hostname !== 'localhost';
161170
const baseOptions = {
162171
container: searchButtonRef.current,
163-
host: siteConfig.customFields.meilisearch.host,
172+
host: useProxy ? `${window.location.origin}/api` : meiliHost,
164173
apiKey: siteConfig.customFields.meilisearch.apiKey,
165174
indexUid: siteConfig.customFields.meilisearch.indexUid,
166175

@@ -256,6 +265,8 @@ function SearchBarContent() {
256265

257266
const search = docsearch(baseOptions);
258267

268+
// If using proxy, docsearch will call `${origin}/api/indexes/<uid>/search`
269+
259270
searchInstanceRef.current = search;
260271
setIsLoaded(true);
261272

0 commit comments

Comments
 (0)