@@ -16,7 +16,9 @@ import {
1616import Translate from '@docusaurus/Translate' ;
1717import useDocusaurusContext from '@docusaurus/useDocusaurusContext' ;
1818import translations from '@theme/SearchTranslations' ;
19+
1920let DocSearchModal = null ;
21+
2022function importDocSearchModalIfNeeded ( ) {
2123 if ( DocSearchModal ) {
2224 return Promise . resolve ( ) ;
@@ -29,6 +31,7 @@ function importDocSearchModalIfNeeded() {
2931 DocSearchModal = Modal ;
3032 } ) ;
3133}
34+
3235function useNavigator ( { externalUrlRegex} ) {
3336 const history = useHistory ( ) ;
3437 const [ navigator ] = useState ( ( ) => {
@@ -46,6 +49,7 @@ function useNavigator({externalUrlRegex}) {
4649 } ) ;
4750 return navigator ;
4851}
52+
4953function useTransformSearchClient ( ) {
5054 const {
5155 siteMetadata : { docusaurusVersion} ,
@@ -58,6 +62,7 @@ function useTransformSearchClient() {
5862 [ docusaurusVersion ] ,
5963 ) ;
6064}
65+
6166function useTransformItems ( props ) {
6267 const processSearchResultUrl = useSearchResultUrlProcessor ( ) ;
6368 const [ transformItems ] = useState ( ( ) => {
@@ -73,6 +78,7 @@ function useTransformItems(props) {
7378 } ) ;
7479 return transformItems ;
7580}
81+
7682function useResultsFooterComponent ( { closeModal} ) {
7783 return useMemo (
7884 ( ) =>
@@ -81,9 +87,11 @@ function useResultsFooterComponent({closeModal}) {
8187 [ closeModal ] ,
8288 ) ;
8389}
90+
8491function Hit ( { hit, children} ) {
8592 return < Link to = { hit . url } > { children } </ Link > ;
8693}
94+
8795function ResultsFooter ( { state, onClose} ) {
8896 const createSearchLink = useSearchLinkCreator ( ) ;
8997 return (
@@ -96,50 +104,75 @@ function ResultsFooter({state, onClose}) {
96104 </ Link >
97105 ) ;
98106}
107+
99108function useSearchParameters ( { contextualSearch, ...props } ) {
100109 function mergeFacetFilters ( f1 , f2 ) {
101110 const normalize = ( f ) => ( typeof f === 'string' ? [ f ] : f ) ;
102111 return [ ...normalize ( f1 ) , ...normalize ( f2 ) ] ;
103112 }
113+
104114 const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters ( ) ;
105115 const configFacetFilters = props . searchParameters ?. facetFilters ?? [ ] ;
116+
117+ // Get the current path to determine which product we're viewing
118+ const path = typeof window !== 'undefined' ? window . location . pathname : '' ;
119+ let product = null ;
120+
121+ // Determine the product based on the URL path
122+ if ( path . startsWith ( '/xpf/' ) ) {
123+ product = 'xpf' ;
124+ } else if ( path . startsWith ( '/docs/' ) ) {
125+ product = 'avalonia' ;
126+ } else if ( path . startsWith ( '/accelerate/' ) ) {
127+ product = 'accelerate' ;
128+ }
129+
130+ // Only add product facet if we've determined a product
131+ const dynamicFacet = product ? [ `product:${ product } ` ] : [ ] ;
132+
133+ // Merge all facet filters
106134 const facetFilters = contextualSearch
107- ? // Merge contextual search filters with config filters
108- mergeFacetFilters ( contextualSearchFacetFilters , configFacetFilters )
109- : // ... or use config facetFilters
110- configFacetFilters ;
111- // We let users override default searchParameters if they want to
135+ ? mergeFacetFilters ( contextualSearchFacetFilters , [
136+ ...configFacetFilters ,
137+ ...dynamicFacet ,
138+ ] )
139+ : mergeFacetFilters ( configFacetFilters , dynamicFacet ) ; // Fix: properly merge configFacetFilters with dynamicFacet
140+
112141 return {
113142 ...props . searchParameters ,
114143 facetFilters,
115144 } ;
116145}
146+
117147function DocSearch ( { externalUrlRegex, ...props } ) {
118148 const navigator = useNavigator ( { externalUrlRegex} ) ;
119149 const searchParameters = useSearchParameters ( { ...props } ) ;
120150 const transformItems = useTransformItems ( props ) ;
121151 const transformSearchClient = useTransformSearchClient ( ) ;
122152 const searchContainer = useRef ( null ) ;
123- // TODO remove "as any" after React 19 upgrade
124153 const searchButtonRef = useRef ( null ) ;
125154 const [ isOpen , setIsOpen ] = useState ( false ) ;
126155 const [ initialQuery , setInitialQuery ] = useState ( undefined ) ;
156+
127157 const prepareSearchContainer = useCallback ( ( ) => {
128158 if ( ! searchContainer . current ) {
129159 const divElement = document . createElement ( 'div' ) ;
130160 searchContainer . current = divElement ;
131161 document . body . insertBefore ( divElement , document . body . firstChild ) ;
132162 }
133163 } , [ ] ) ;
164+
134165 const openModal = useCallback ( ( ) => {
135166 prepareSearchContainer ( ) ;
136167 importDocSearchModalIfNeeded ( ) . then ( ( ) => setIsOpen ( true ) ) ;
137168 } , [ prepareSearchContainer ] ) ;
169+
138170 const closeModal = useCallback ( ( ) => {
139171 setIsOpen ( false ) ;
140172 searchButtonRef . current ?. focus ( ) ;
141173 setInitialQuery ( undefined ) ;
142174 } , [ ] ) ;
175+
143176 const handleInput = useCallback (
144177 ( event ) => {
145178 if ( event . key === 'f' && ( event . metaKey || event . ctrlKey ) ) {
@@ -153,14 +186,17 @@ function DocSearch({externalUrlRegex, ...props}) {
153186 } ,
154187 [ openModal ] ,
155188 ) ;
189+
156190 const resultsFooterComponent = useResultsFooterComponent ( { closeModal} ) ;
191+
157192 useDocSearchKeyboardEvents ( {
158193 isOpen,
159194 onOpen : openModal ,
160195 onClose : closeModal ,
161196 onInput : handleInput ,
162197 searchButtonRef,
163198 } ) ;
199+
164200 return (
165201 < >
166202 < Head >
@@ -208,29 +244,16 @@ function DocSearch({externalUrlRegex, ...props}) {
208244 </ >
209245 ) ;
210246}
211- export default function SearchBar ( props ) {
212- const path = typeof window !== 'undefined' ? window . location . pathname : '' ;
213- let product = null ;
214247
215- if ( path . startsWith ( '/xpf/' ) ) {
216- product = 'xpf' ;
217- } else if ( path . startsWith ( '/docs/' ) ) {
218- product = 'avalonia' ;
219- } else if ( path . startsWith ( '/accelerate/' ) ) {
220- product = 'accelerate' ;
248+ export default function SearchBar ( props ) {
249+ const { siteConfig} = useDocusaurusContext ( ) ;
250+ const searchConfig = siteConfig . themeConfig . algolia ;
251+
252+ // If Algolia config is missing, fall back to the default search bar
253+ if ( ! searchConfig || ! searchConfig . appId || ! searchConfig . apiKey || ! searchConfig . indexName ) {
254+ console . warn ( 'Algolia search configuration is incomplete. Check your themeConfig.algolia settings in docusaurus.config.js' ) ;
255+ return < DefaultSearchBar { ...props } /> ;
221256 }
222-
223- const dynamicSearchParameters = product
224- ? { facetFilters : [ `product:${ product } ` ] }
225- : { } ;
226-
227- return (
228- < DefaultSearchBar
229- { ...props }
230- searchParameters = { {
231- ...props . searchParameters ,
232- ...dynamicSearchParameters ,
233- } }
234- />
235- ) ;
257+
258+ return < DocSearch { ...searchConfig } { ...props } /> ;
236259}
0 commit comments