Skip to content

Commit 57d4b3d

Browse files
committed
fix: allow builds without the segment API key
convert the error to a warning, to allow local development without the key
1 parent de68df0 commit 57d4b3d

File tree

7 files changed

+223
-27
lines changed

7 files changed

+223
-27
lines changed

apify-docs-theme/src/theme/Navbar/Content/index.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import NavbarLogo from '@theme/Navbar/Logo';
88
import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle';
99
import NavbarSearch from '@theme/Navbar/Search';
1010
import NavbarItem from '@theme/NavbarItem';
11+
import SearchBar from '@theme/SearchBar';
1112
import React from 'react';
1213

13-
import SearchBar from '../../SearchBar';
14+
// import SearchBar from '../../SearchBar';
1415
import NavbarCTA from '../CTA';
1516

1617
function NavbarItems({ items }) {

apify-docs-theme/src/theme/SearchBar/index.js

Lines changed: 172 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
// eslint-disable-next-line simple-import-sort/imports
22
import BrowserOnly from '@docusaurus/BrowserOnly';
33
import RouterLink from '@docusaurus/Link';
4-
import { useHistory, useLocation } from '@docusaurus/router';
4+
// import { useHistory, useLocation } from '@docusaurus/router';
55
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
6-
import React, { useCallback } from 'react';
6+
// import React, { useCallback } from 'react';
7+
import React, { useEffect, useState } from 'react';
78

8-
import { ApifySearch } from '@apify/docs-search-modal';
9+
// import { ApifySearch } from '@apify/docs-search-modal';
910

1011
// needs to be imported as the last thing, so that it can override the default styles
1112
// TODO: update simple-import-sort to allow importing css as last.
1213
import './styles.css';
14+
import { ControlKeyIcon, SearchIcon } from '@apify/docs-search-modal/dist/utils/icons';
1315

1416
/**
1517
* Tests whether the given href is pointing to the current docusaurus instance (so we can use the router link).
@@ -40,37 +42,184 @@ export function Link(props) {
4042
return <a {...props}>{props.children}</a>;
4143
}
4244

45+
// export default function SearchBar({ onClick }) {
46+
// const { siteConfig } = useDocusaurusContext();
47+
// const location = useLocation();
48+
// const history = useHistory();
49+
//
50+
// const navigate = useCallback((href) => {
51+
// const shortHref = href.substring('https://docs.apify.com'.length);
52+
//
53+
// if (matchesCurrentInstance(shortHref, siteConfig.baseUrl)) {
54+
// return history.push(shortHref);
55+
// }
56+
// return window.location.assign(href);
57+
// }, [history, siteConfig.baseUrl]);
58+
//
59+
// const getVersion = useCallback(() => {
60+
// const match = location.pathname.match(/\/(\d+\.\d+|next)/);
61+
//
62+
// return match ? match[1] : 'latest';
63+
// }, [location]);
64+
//
65+
// return (
66+
// <BrowserOnly>
67+
// {() => (
68+
// <div onClick={onClick}>
69+
// <ApifySearch
70+
// algoliaAppId={siteConfig.themeConfig.algolia.appId}
71+
// algoliaIndexName='apify_sdk_v2'
72+
// algoliaKey={siteConfig.themeConfig.algolia.apiKey}
73+
// filters={`version:${getVersion()}`}
74+
// navigate={navigate}
75+
// />
76+
// </div>
77+
// )}
78+
// </BrowserOnly>
79+
// );
80+
// }
81+
4382
export default function SearchBar({ onClick }) {
44-
const { siteConfig } = useDocusaurusContext();
45-
const location = useLocation();
46-
const history = useHistory();
83+
const [variant, setVariant] = useState(null);
4784

48-
const navigate = useCallback((href) => {
49-
const shortHref = href.substring('https://docs.apify.com'.length);
85+
useEffect(() => {
86+
const storedVariant = localStorage.getItem('search-provider');
87+
88+
if (storedVariant) {
89+
setVariant(storedVariant);
90+
} else {
91+
const assignedVariant = Math.random() < 0.5 ? 'inkeep' : 'kapa';
92+
localStorage.setItem('search-provider', assignedVariant);
93+
setVariant(assignedVariant);
94+
}
95+
}, []);
96+
97+
const inkeepApiKey = process.env.LOCALHOST || process.env.DEV
98+
? 'bbbb9f1001a9b66f282431a80bb743a24e2bdefb85d4f1e4' // development, works with localhost
99+
: '8af30e40009f26622237f75aab8256064c26a3063717c48a';
100+
101+
onClick = () => {
102+
if (variant === 'kapa') {
103+
if (window.Kapa && typeof window.Kapa.open === 'function') {
104+
window.Kapa.open();
105+
} else {
106+
console.error('Kapa.ai widget is not available.');
107+
}
108+
return;
109+
}
50110

51-
if (matchesCurrentInstance(shortHref, siteConfig.baseUrl)) {
52-
return history.push(shortHref);
111+
if (variant !== 'inkeep') {
112+
console.warn('Unknown search variant:', variant);
113+
return;
53114
}
54-
return window.location.assign(href);
55-
}, [history, siteConfig.baseUrl]);
56115

57-
const getVersion = useCallback(() => {
58-
const match = location.pathname.match(/\/(\d+\.\d+|next)/);
116+
if (window.Inkeep) {
117+
const config = {
118+
baseSettings: {
119+
apiKey: inkeepApiKey, // production, only works on apify.com (any subdomain)
120+
organizationDisplayName: 'Apify',
121+
primaryBrandColor: '#FF9013',
122+
transformSource: (source) => {
123+
if (source.contentType === 'documentation') {
124+
return {
125+
...source,
126+
tabs: [...(source.tabs || []), 'Docs'],
127+
};
128+
}
129+
return source;
130+
},
131+
trigger: {
132+
disableDefaultTrigger: true,
133+
},
134+
theme: {
135+
styles: [
136+
{
137+
key: 'main',
138+
type: 'link',
139+
value: '/inkeep-overrides.css',
140+
},
141+
],
142+
},
143+
},
144+
modalSettings: {
145+
onOpenChange: handleOpenChange,
146+
},
147+
searchSettings: {
148+
tabs: [
149+
'All',
150+
'Docs',
151+
'Publications',
152+
'PDFs',
153+
'GitHub',
154+
'Forums',
155+
'Discord',
156+
'Slack',
157+
'StackOverflow',
158+
],
159+
},
160+
aiChatSettings: {
161+
aiAssistantAvatar: 'https://intercom.help/apify/assets/favicon',
162+
chatSubjectName: 'Apify',
163+
exampleQuestions: [
164+
'What is an Actor?',
165+
'How to use my own proxies?',
166+
'How to integrate Apify Actors with GitHub?',
167+
'How to share key-value stores between runs?',
168+
],
169+
getHelpOptions: [
170+
{
171+
action: {
172+
type: 'open_link',
173+
url: 'https://apify.com/contact',
174+
},
175+
icon: {
176+
builtIn: 'IoChatbubblesOutline',
177+
},
178+
name: 'Contact Us',
179+
},
180+
],
181+
},
182+
};
183+
const modal = window.Inkeep.ModalSearchAndChat(config);
59184

60-
return match ? match[1] : 'latest';
61-
}, [location]);
185+
function handleOpenChange(newOpen) {
186+
modal.update({ modalSettings: { isOpen: newOpen } });
187+
}
188+
189+
modal.update({ modalSettings: { isOpen: true } });
190+
} else {
191+
console.error('Kapa.ai widget is not available.');
192+
}
193+
};
194+
195+
const [key, setKey] = useState(null);
196+
197+
useEffect(() => {
198+
if (typeof navigator !== 'undefined') {
199+
const isMac = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
200+
setKey(isMac ? '⌘' : 'ctrl');
201+
}
202+
}, []);
62203

63204
return (
64205
<BrowserOnly>
65206
{() => (
66207
<div onClick={onClick}>
67-
<ApifySearch
68-
algoliaAppId={siteConfig.themeConfig.algolia.appId}
69-
algoliaIndexName='apify_sdk_v2'
70-
algoliaKey={siteConfig.themeConfig.algolia.apiKey}
71-
filters={`version:${getVersion()}`}
72-
navigate={navigate}
73-
/>
208+
<button type="button" className="DocSearch DocSearch-Button" aria-label="Search">
209+
<span className="DocSearch-Button-Container">
210+
<SearchIcon/>
211+
<span className="DocSearch-Button-Placeholder">Search</span>
212+
</span>
213+
<span className="DocSearch-Button-Keys">
214+
{key !== null && (<>
215+
<kbd className="DocSearch-Button-Key">
216+
{key === 'ctrl' ? <ControlKeyIcon/> : key}
217+
</kbd>
218+
<kbd className="DocSearch-Button-Key">K</kbd>
219+
</>)}
220+
</span>
221+
222+
</button>
74223
</div>
75224
)}
76225
</BrowserOnly>

docusaurus.config.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,33 @@ module.exports = {
1717
trailingSlash: false,
1818
organizationName: 'apify',
1919
projectName: 'apify-docs',
20-
scripts: ['/js/custom.js'],
20+
scripts: [
21+
'/js/custom.js',
22+
{
23+
src: 'https://widget.kapa.ai/kapa-widget.bundle.js',
24+
'data-website-id': 'a9937f98-9c9d-44d9-a433-fec4cb1c114d',
25+
'data-project-name': 'Apify',
26+
'data-modal-title': 'Apify AI Assistant',
27+
'data-project-color': '#ffffff',
28+
'data-button-hide': 'true',
29+
'data-search-mode-enabled': 'true',
30+
'data-project-logo': 'https://blog.apify.com/content/images/2025/02/Apify_logo.png',
31+
'data-modal-example-questions': 'How to run an Actor?,Create a version of an Actor?',
32+
'data-modal-override-open-id': 'ask-ai-input',
33+
'data-modal-override-open-class': 'search-input',
34+
'data-font-size-xs': '1.2rem',
35+
'data-font-size-sm': '1.4rem',
36+
'data-font-size-md': '1.6rem',
37+
'data-font-size-lg': '1.8rem',
38+
'data-font-size-xl': '2.0rem',
39+
async: true,
40+
},
41+
{
42+
src: 'https://cdn.jsdelivr.net/npm/@inkeep/cxkit-js@0.5/dist/embed.js',
43+
type: 'module',
44+
async: true,
45+
},
46+
],
2147
future: {
2248
experimental_faster: {
2349
// swcJsLoader: true,

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

static/inkeep-overrides.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.inkeep-widget-vars {
2+
font-size: 1.6rem !important;
3+
--ikp-font-size-3xs: 0.72rem !important;
4+
--ikp-font-size-2xs: 1rem !important;
5+
--ikp-font-size-xs: 1.2rem !important;
6+
--ikp-font-size-1sm: 1.3rem !important;
7+
--ikp-font-size-sm: 1.4rem !important;
8+
--ikp-font-size-2sm: 1.5rem !important;
9+
--ikp-font-size-md: 1.6rem !important;
10+
--ikp-font-size-lg: 1.8rem !important;
11+
--ikp-font-size-xl: 2rem !important;
12+
--ikp-font-size-2xl: 2.4rem !important;
13+
--ikp-font-size-3xl: 3rem !important;
14+
--ikp-font-size-4xl: 3.6rem !important;
15+
--ikp-font-size-5xl: 4.8rem !important;
16+
--ikp-font-size-6xl: 6rem !important;
17+
--ikp-font-size-7xl: 7.2rem !important;
18+
--ikp-font-size-8xl: 9.6rem !important;
19+
--ikp-font-size-9xl: 12.8rem !important;
20+
}

0 commit comments

Comments
 (0)