From f9ed661e437eb7d770e54a86648d41b624dd2766 Mon Sep 17 00:00:00 2001 From: Ganesh Patil <7030871503ganeshpatil@gmail.com> Date: Mon, 5 Jan 2026 15:32:26 +0530 Subject: [PATCH 1/5] fix(search): limit search result snippets to 200 chars and increase result cap Truncates each search result description to 200 characters Prevents result list overflow that hides other hits Updated search result return limit from 5 to 10 Added CSS line-clamp for cleaner result display --- antora-ui-camel/src/css/header.css | 4 ++ .../src/js/vendor/algoliasearch.bundle.js | 61 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/antora-ui-camel/src/css/header.css b/antora-ui-camel/src/css/header.css index ae4fa531972..8b265ec82da 100644 --- a/antora-ui-camel/src/css/header.css +++ b/antora-ui-camel/src/css/header.css @@ -380,6 +380,10 @@ html:not([data-scroll='0']) .navbar { .result_summary { color: var(--color-jet-50); padding-top: 0.3rem; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; } #search_results div.footer-search { diff --git a/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js b/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js index eb436617b41..a4b692ab8df 100644 --- a/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js +++ b/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js @@ -3,6 +3,9 @@ const algoliasearch = require('algoliasearch/lite') + const MAX_SNIPPET_LENGTH = 200 + const RESULTS_LIMIT = 10 + // Sub-projects to exclude from main search - users can browse these directly const EXCLUDED_SUBPROJECTS = [ '/camel-k/', @@ -21,6 +24,60 @@ }) } + function truncateHighlightedHtml (html, maxChars) { + if (!html || maxChars <= 0) return '' + + const template = document.createElement('template') + template.innerHTML = html + + let remaining = maxChars + let truncated = false + + const TEXT_NODE = 3 + const ELEMENT_NODE = 1 + + function cloneUntilLimit (node) { + if (remaining <= 0) return null + + if (node.nodeType === TEXT_NODE) { + const text = node.nodeValue || '' + if (text.length <= remaining) { + remaining -= text.length + return document.createTextNode(text) + } + truncated = true + const slice = text.slice(0, remaining) + remaining = 0 + return document.createTextNode(slice) + } + + if (node.nodeType === ELEMENT_NODE) { + const el = node + const cloned = el.cloneNode(false) + for (const child of Array.from(el.childNodes)) { + if (remaining <= 0) break + const childClone = cloneUntilLimit(child) + if (childClone) cloned.appendChild(childClone) + } + return cloned + } + + return null + } + + const outFragment = document.createDocumentFragment() + for (const child of Array.from(template.content.childNodes)) { + if (remaining <= 0) break + const childClone = cloneUntilLimit(child) + if (childClone) outFragment.appendChild(childClone) + } + if (truncated) outFragment.appendChild(document.createTextNode('…')) + + const container = document.createElement('div') + container.appendChild(outFragment) + return container.innerHTML + } + window.addEventListener('load', () => { const client = algoliasearch('V62SL4FFIW', '1b7e52df4759e32dd49adedb286997f6') const index = client.initIndex('apache_camel') @@ -70,7 +127,7 @@ // Filter out sub-project results to focus on camel-core documentation const filteredHits = results.hits.filter(function (hit) { return !isSubProjectUrl(hit.url) - }).slice(0, 5) + }).slice(0, RESULTS_LIMIT) const data = filteredHits.reduce((data, hit) => { const section = hit.hierarchy.lvl0 const sectionKey = `${section}-${hit.version || ''}` @@ -86,7 +143,7 @@ .slice(1) .filter((lvl) => lvl !== null) .join(' / '), - snippet: hit._highlightResult.content.value, + snippet: truncateHighlightedHtml(hit._highlightResult.content.value, MAX_SNIPPET_LENGTH), }) return data From e93bac39e1be5222da1071cd2258c864a3882223 Mon Sep 17 00:00:00 2001 From: Ganesh Patil <7030871503ganeshpatil@gmail.com> Date: Tue, 6 Jan 2026 00:29:51 +0530 Subject: [PATCH 2/5] fix(search): prioritize core docs and limit input length (#1459) - Add 200 character max length to search input (HTML + JS validation) - Prioritize core documentation (manual, user-guide, architecture) over component pages - Add CSS constraints (max-width, min-width) to prevent dropdown UI overflow - Fetch more results (20) from Algolia then filter and sort to top 10 - Core docs patterns: /manual/, /user-guide/, /architecture/, /getting-started/, /faq/ - Component pages now rank lower in search results --- antora-ui-camel/src/css/header.css | 2 + .../src/js/vendor/algoliasearch.bundle.js | 59 ++++++++++++++++++- .../src/partials/header-content.hbs | 2 +- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/antora-ui-camel/src/css/header.css b/antora-ui-camel/src/css/header.css index 8b265ec82da..9eccac2bd0a 100644 --- a/antora-ui-camel/src/css/header.css +++ b/antora-ui-camel/src/css/header.css @@ -303,6 +303,8 @@ html:not([data-scroll='0']) .navbar { margin-right: 10px; overflow-y: auto; max-height: 80vh; + max-width: min(600px, 90vw); + min-width: 300px; scrollbar-width: thin; /* Firefox */ } diff --git a/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js b/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js index a4b692ab8df..241b1b97063 100644 --- a/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js +++ b/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js @@ -5,6 +5,7 @@ const MAX_SNIPPET_LENGTH = 200 const RESULTS_LIMIT = 10 + const MAX_INPUT_LENGTH = 200 // Sub-projects to exclude from main search - users can browse these directly const EXCLUDED_SUBPROJECTS = [ @@ -16,6 +17,15 @@ '/camel-karaf/', ] + // Core docs patterns - these should rank higher than component pages + const CORE_DOCS_PATTERNS = [ + '/manual/', + '/user-guide/', + '/architecture/', + '/getting-started/', + '/faq/', + ] + // Check if a URL belongs to a sub-project that should be filtered out function isSubProjectUrl (url) { if (!url) return false @@ -24,6 +34,40 @@ }) } + // Check if a URL points to core documentation (should rank higher) + function isCoreDocsUrl (url) { + if (!url) return false + return CORE_DOCS_PATTERNS.some(function (pattern) { + return url.indexOf(pattern) !== -1 + }) + } + + // Check if a URL points to component documentation + function isComponentUrl (url) { + if (!url) return false + return url.indexOf('/components/') !== -1 + } + + // Sort hits to prioritize core docs over components + function sortByCoreDocs (hits) { + return hits.sort(function (a, b) { + var aIsCore = isCoreDocsUrl(a.url) + var bIsCore = isCoreDocsUrl(b.url) + var aIsComponent = isComponentUrl(a.url) + var bIsComponent = isComponentUrl(b.url) + + // Core docs first + if (aIsCore && !bIsCore) return -1 + if (!aIsCore && bIsCore) return 1 + + // Components last + if (aIsComponent && !bIsComponent) return 1 + if (!aIsComponent && bIsComponent) return -1 + + return 0 + }) + } + function truncateHighlightedHtml (html, maxChars) { if (!html || maxChars <= 0) return '' @@ -104,6 +148,13 @@ e.stopPropagation() }) + // Enforce max input length as backup to HTML maxlength attribute + search.addEventListener('input', function () { + if (search.value.length > MAX_INPUT_LENGTH) { + search.value = search.value.substring(0, MAX_INPUT_LENGTH) + } + }) + search.addEventListener( 'keyup', debounce((key) => { @@ -121,14 +172,16 @@ cancel.style.display = 'block' index .search(search.value, { - hitsPerPage: 10, + hitsPerPage: 20, }) .then((results) => { // Filter out sub-project results to focus on camel-core documentation const filteredHits = results.hits.filter(function (hit) { return !isSubProjectUrl(hit.url) - }).slice(0, RESULTS_LIMIT) - const data = filteredHits.reduce((data, hit) => { + }) + // Sort to prioritize core docs over components + const sortedHits = sortByCoreDocs(filteredHits).slice(0, RESULTS_LIMIT) + const data = sortedHits.reduce((data, hit) => { const section = hit.hierarchy.lvl0 const sectionKey = `${section}-${hit.version || ''}` diff --git a/antora-ui-camel/src/partials/header-content.hbs b/antora-ui-camel/src/partials/header-content.hbs index 3173cfc98e4..4ae105d550c 100644 --- a/antora-ui-camel/src/partials/header-content.hbs +++ b/antora-ui-camel/src/partials/header-content.hbs @@ -17,7 +17,7 @@
From 6ecfa35208b466beab1ebe99fdc7ef380abf037f Mon Sep 17 00:00:00 2001 From: Ganesh Patil <7030871503ganeshpatil@gmail.com> Date: Tue, 6 Jan 2026 09:42:16 +0530 Subject: [PATCH 3/5] fix: remove duplicate search results for same parent page (#1464) --- .../src/js/vendor/algoliasearch.bundle.js | 96 ++++++++++++++++++- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js b/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js index 241b1b97063..5951d366b5c 100644 --- a/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js +++ b/antora-ui-camel/src/js/vendor/algoliasearch.bundle.js @@ -68,6 +68,91 @@ }) } + // Extract the parent page path from a URL (removes anchor and trailing segments) + function getParentPagePath (url) { + if (!url) return '' + // Remove anchor fragment + var path = url.split('#')[0] + // Normalize trailing slash + if (path.endsWith('/')) { + path = path.slice(0, -1) + } + return path + } + + // Check if hit represents a sub-section of a page (has anchor or deeper hierarchy) + function isSubSection (hit) { + if (!hit || !hit.url) return false + return hit.url.indexOf('#') !== -1 + } + + // Get the breadcrumb depth (number of hierarchy levels) + function getBreadcrumbDepth (hit) { + if (!hit || !hit.hierarchy) return 0 + return Object.values(hit.hierarchy).filter(function (lvl) { + return lvl !== null + }).length + } + + // Remove duplicate results for the same parent page + // When parent page is a direct match, exclude its sub-sections + function deduplicateHits (hits, query) { + var seenPages = {} + var parentMatches = {} + var queryLower = (query || '').toLowerCase().trim() + + // First pass: identify parent pages that match the query directly + hits.forEach(function (hit) { + var parentPath = getParentPagePath(hit.url) + var hierarchy = hit.hierarchy || {} + + // Check if any top-level hierarchy matches the search query + var lvl1 = (hierarchy.lvl1 || '').toLowerCase() + var lvl0 = (hierarchy.lvl0 || '').toLowerCase() + + if (lvl1 && lvl1.indexOf(queryLower) !== -1) { + parentMatches[parentPath] = true + } + if (lvl0 && lvl0.indexOf(queryLower) !== -1) { + parentMatches[parentPath] = true + } + }) + + // Second pass: filter out sub-sections when parent is already matched + return hits.filter(function (hit) { + var parentPath = getParentPagePath(hit.url) + var isSubSec = isSubSection(hit) + var depth = getBreadcrumbDepth(hit) + + // If this is a sub-section and parent page already matched, skip it + if (isSubSec && parentMatches[parentPath]) { + // Only keep the main page hit, not sub-sections + if (seenPages[parentPath]) { + return false + } + } + + // For component pages, only show the main entry (depth <= 2) + if (isComponentUrl(hit.url) && depth > 2 && seenPages[parentPath]) { + return false + } + + // Track that we've seen this parent page + if (!seenPages[parentPath]) { + seenPages[parentPath] = { depth: depth, hit: hit } + return true + } + + // If we already have this page, only keep if it's a better match (shallower) + if (depth < seenPages[parentPath].depth) { + seenPages[parentPath] = { depth: depth, hit: hit } + return true + } + + return false + }) + } + function truncateHighlightedHtml (html, maxChars) { if (!html || maxChars <= 0) return '' @@ -170,17 +255,20 @@ return } cancel.style.display = 'block' + var searchQuery = search.value index - .search(search.value, { - hitsPerPage: 20, + .search(searchQuery, { + hitsPerPage: 50, }) .then((results) => { // Filter out sub-project results to focus on camel-core documentation const filteredHits = results.hits.filter(function (hit) { return !isSubProjectUrl(hit.url) }) - // Sort to prioritize core docs over components - const sortedHits = sortByCoreDocs(filteredHits).slice(0, RESULTS_LIMIT) + // Remove duplicate results for the same parent page + const dedupedHits = deduplicateHits(filteredHits, searchQuery) + // Sort to prioritize core docs over components and limit results + const sortedHits = sortByCoreDocs(dedupedHits).slice(0, RESULTS_LIMIT) const data = sortedHits.reduce((data, hit) => { const section = hit.hierarchy.lvl0 const sectionKey = `${section}-${hit.version || ''}` From 03aee2dfe17f741dd030a3fa19eafa8f554db680 Mon Sep 17 00:00:00 2001 From: Ganesh Patil <7030871503ganeshpatil@gmail.com> Date: Thu, 15 Jan 2026 16:09:24 +0530 Subject: [PATCH 4/5] docs: add Algolia DocSearch configuration for improved search indexing This commit adds the .docsearch.config.json configuration file to improve search indexing on the Apache Camel website. The configuration addresses GitHub issue #1209 where several keywords were not discoverable through search. Key improvements: - Enables indexing of table content in component documentation (fixes keywords like 'PyTorch', 'Bradley', 'firmata' not appearing in search results) - Extends crawling to all documentation versions (next, latest, release branches) instead of only canonical pages - Improves content extraction by indexing all heading levels (h1-h6), table cells, code blocks, lists, and definition lists - Excludes navigation, sidebars, and footer elements to improve search quality The configuration follows Algolia DocSearch v3 standards and includes: - CSS selectors for comprehensive content extraction - Multi-version support with appropriate search rankings - Custom settings for optimal search behavior - Documentation explaining the configuration for future maintenance Related to issue #1209: The search is not finding several fields --- .docsearch.README.md | 111 ++++++++++++++++++++++++++++++++++++ .docsearch.config.json | 125 +++++++++++++++++++++++++++++++++++++++++ README.md | 29 ++++++++++ 3 files changed, 265 insertions(+) create mode 100644 .docsearch.README.md create mode 100644 .docsearch.config.json diff --git a/.docsearch.README.md b/.docsearch.README.md new file mode 100644 index 00000000000..2310abe4854 --- /dev/null +++ b/.docsearch.README.md @@ -0,0 +1,111 @@ +# DocSearch Configuration + +This directory contains the Algolia DocSearch configuration for the Apache Camel website. + +## Overview + +The `.docsearch.config.json` file defines how Algolia's crawler indexes the Camel website for search functionality. This configuration ensures that all relevant content is discoverable through the site search, including: + +- All component documentation (not just canonical versions) +- Tables with component specifications and supported models +- Metadata sections and inline code +- Multiple documentation versions (next, latest, and release branches) + +## Key Configuration Elements + +### Index Settings (`index`) +- **name**: `apache_camel` - The Algolia index where content is stored +- **startUrls**: Entry points for the crawler +- **pathsToMatch**: URL patterns to include in indexing +- **pathsToIgnore**: URLs to skip (search pages, error pages, etc.) +- **includeHeadingLevels**: All heading levels (h1-h6) are indexed for better navigation + +### Content Selectors (`selectors`) + +These CSS selectors define what content gets indexed: + +- **lvl0-lvl5**: Heading hierarchy (h1-h6) used to build the breadcrumb structure +- **text**: Main content to index including: + - Paragraphs (`p`), list items (`li`) + - Table cells (`td`, `th`) - **Important for component specs** + - Definition terms (`dt`, `dd`) + - Code blocks (`code`, `pre`) + +This ensures keywords like "PyTorch" in Model Zoo tables are indexed, fixing issue #1209. + +### Exclusions (`selectors_exclude`) + +Navigation, sidebars, footers, and other non-content elements are excluded to improve search quality: +- `.no_index`, `[data-no-index]` - Custom exclusion attributes +- Navigation elements: `nav`, `.navbar`, `.menu`, `.sidebar`, `.toc` +- Footer and copyright +- Hidden elements: `.hidden`, `[aria-hidden='true']` + +### Crawling Rules (`crawler`) + +- **maxDepth**: 20 - Allows deep navigation through component docs +- **maxUrls**: 50,000 - Sufficient for Camel's comprehensive documentation +- **sitemapUrls**: Uses sitemap for efficient crawling +- **timeoutMs**: 30,000 - Adequate for large pages with tables + +### Multi-Version Support (`start_urls`) + +The configuration crawls multiple documentation versions: + +1. **next** (page_rank: 5) - Development version +2. **latest** (page_rank: 5) - Latest stable +3. **\d+\.\d+\.\x** (page_rank: 4) - Release branches (4.4.x, 4.10.x, etc.) +4. **manual** (page_rank: 7) - Core documentation (highest priority) +5. **docs** (page_rank: 6) - General documentation +6. **blog** (page_rank: 3) - Blog posts + +This addresses the issue where only canonical (4.4.x) pages were indexed. + +### Search Behavior (`custom_settings`) + +- **searchableAttributes**: Fields available for full-text search +- **separatorsToIndex**: Include underscores, dots, and dashes in search (important for component names like `camel-k`) +- **attributeForDistinctResults**: Deduplicate results by URL to avoid showing the same page multiple times + +## Maintenance + +When making changes to this configuration: + +1. **Test locally** - Build the site and verify crawling works +2. **Document changes** - Explain why selectors or URLs were modified +3. **Consider impacts** - Changes affect search indexing across all users +4. **Verify coverage** - Use Algolia dashboard to check what's indexed + +### Common Modifications + +**Adding new documentation sections:** +```json +{ + "url": "https://camel.apache.org/new-section/", + "page_rank": 5 +} +``` + +**Excluding problematic content:** +```json +"selectors_exclude": [ + ".no_index", + ".problematic-element" +] +``` + +**Adjusting content extraction:** +Modify the `text` selector in the `selectors` section to include additional elements. + +## Related Issue + +- **Issue #1209**: "The search is not finding several fields" + - Problem: Keywords like Bradley, firmata, PyTorch not indexed from component documentation + - Root cause: Missing configuration for table content and non-canonical versions + - Solution: This configuration file with improved selectors and multi-version crawling + +## References + +- [Algolia DocSearch Documentation](https://docsearch.algolia.com/) +- [Camel Website GitHub](https://github.com/apache/camel-website) +- [Issue #1209](https://github.com/apache/camel-website/issues/1209) diff --git a/.docsearch.config.json b/.docsearch.config.json new file mode 100644 index 00000000000..66f3f31f2dc --- /dev/null +++ b/.docsearch.config.json @@ -0,0 +1,125 @@ +{ + "index": { + "name": "apache_camel", + "startUrls": [ + "https://camel.apache.org/" + ], + "ignoreCanonicalTo": false, + "pathsToMatch": [ + "https://camel.apache.org/**" + ], + "pathsToIgnore": [ + "https://camel.apache.org/search", + "https://camel.apache.org/404.html" + ], + "includeHeadingLevels": [1, 2, 3, 4, 5, 6], + "stripQueryParameters": true + }, + "crawler": { + "userAgent": "Algolia Crawler", + "maxDepth": 20, + "maxUrls": 50000, + "waitUntilFired": true, + "timeoutMs": 30000, + "sitemapUrls": [ + "https://camel.apache.org/sitemap.xml" + ], + "ignoreRobotsTxt": false, + "allowedDomains": [ + "camel.apache.org" + ] + }, + "selectors": { + "lvl0": { + "selector": "h1", + "global": true, + "default_value": "Documentation" + }, + "lvl1": "h2", + "lvl2": "h3", + "lvl3": "h4", + "lvl4": "h5", + "lvl5": "h6", + "text": "p, li, td, th, dt, dd, span:not(.tooltip), div:not([class*='hidden']), table tbody, code, pre" + }, + "selectors_exclude": [ + ".no_index", + "[data-no-index]", + ".sidebar", + ".breadcrumb", + "nav", + ".navbar", + ".menu", + ".toc", + "footer", + ".footer", + ".copyright", + ".hide", + ".hidden", + "[aria-hidden='true']", + "script", + "style", + ".language-toggle", + ".sidebar-toggle" + ], + "min_indexed_level": 1, + "only_content_level": false, + "start_urls": [ + { + "url": "https://camel.apache.org/components/next/", + "page_rank": 5 + }, + { + "url": "https://camel.apache.org/components/latest/", + "page_rank": 5 + }, + { + "url": "https://camel.apache.org/components/\\d+\\.\\d+\\.x/", + "page_rank": 4 + }, + { + "url": "https://camel.apache.org/manual/", + "page_rank": 7 + }, + { + "url": "https://camel.apache.org/docs/", + "page_rank": 6 + }, + { + "url": "https://camel.apache.org/blog/", + "page_rank": 3 + }, + { + "url": "https://camel.apache.org/", + "page_rank": 8 + } + ], + "stop_urls": [ + "\\?", + "#" + ], + "custom_settings": { + "separatorsToIndex": "_.-", + "attributesForFaceting": [ + "version" + ], + "attributesToIndex": [ + "hierarchy", + "content", + "url" + ], + "minWordSizefor1Typo": 4, + "minWordSizefor2Typos": 8, + "exactOnSingleWordQuery": "none", + "attributeForDistinctResults": "url", + "searchableAttributes": [ + "hierarchy.lvl0", + "hierarchy.lvl1", + "hierarchy.lvl2", + "hierarchy.lvl3", + "hierarchy.lvl4", + "hierarchy.lvl5", + "content" + ] + } +} diff --git a/README.md b/README.md index 62a0c645f5b..81c42a8ceb2 100644 --- a/README.md +++ b/README.md @@ -453,6 +453,35 @@ all generated sources in the project first. Of course this then takes some more time than an optimized rebuild (time to grab another coffee!). +## Search Indexing Configuration + +The website uses [Algolia DocSearch](https://docsearch.algolia.com/) to provide site-wide search functionality. The search configuration is defined in [`.docsearch.config.json`](.docsearch.config.json). + +### What is indexed + +The configuration ensures that Algolia's crawler indexes: +- All documentation versions (development `next`, latest, and release branches like `4.4.x`) +- Component specifications and tables (fixing issue #1209) +- All heading levels and content blocks +- Code blocks and inline code snippets + +### Maintaining the search configuration + +If you need to modify what gets indexed or how content is crawled: + +1. Edit [`.docsearch.config.json`](.docsearch.config.json) to change selectors or crawling rules +2. Review the detailed documentation in [`.docsearch.README.md`](.docsearch.README.md) +3. Test your changes by building the site locally: `yarn build` +4. Verify content is indexable by visiting the search functionality in the preview + +Key elements to be aware of: +- **Selectors** define what HTML elements are indexed (headings, paragraphs, tables, code) +- **start_urls** control which parts of the site are crawled and their search priority +- **selectors_exclude** specify elements to skip (navigation, sidebars, footers) +- **custom_settings** control search behavior and index settings + +For more details, see [`.docsearch.README.md`](.docsearch.README.md). + # Checks, publishing the website The content of the website, as built by the [Camel.website](https://ci-builds.apache.org/job/Camel/job/Camel.website/job/main/) From b52e5881336c9b1367f6efca01dde894b237011c Mon Sep 17 00:00:00 2001 From: Ganesh Patil <7030871503ganeshpatil@gmail.com> Date: Thu, 15 Jan 2026 16:39:24 +0530 Subject: [PATCH 5/5] fix: improve regex pattern for version URL matching in Algolia configuration - Changed version pattern from literal \d+\.\d+\.x to capture groups (\d+)\.(\d+)\.x - Ensures proper regex matching for URLs like 4.4.x, 4.10.x, etc. - Improves compatibility with Algolia DocSearch crawler - Addresses Copilot review feedback on regex pattern safety --- .docsearch.config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.docsearch.config.json b/.docsearch.config.json index 66f3f31f2dc..557fd70e84f 100644 --- a/.docsearch.config.json +++ b/.docsearch.config.json @@ -74,7 +74,7 @@ "page_rank": 5 }, { - "url": "https://camel.apache.org/components/\\d+\\.\\d+\\.x/", + "url": "https://camel.apache.org/components/(\\d+)\\.(\\d+)\\.x/", "page_rank": 4 }, {