Knowledge Graph Wiki Plugin
The Knowledge Graph Wiki Plugin is a self-contained front-end plugin that embeds into any
SearchBlox deployment. It provides a rich UI for exploring a SearchBlox Knowledge Graph —
browsing entities, reading documents, navigating relationships and topics, and visualising the
graph with an interactive D3 force-directed canvas.
The plugin ships as a static build (dist/) and is dropped into a web server as a folder (e.g.
/plugins/kgwiki1/). All configuration is done via hidden fields in index.html —
no rebuild needed for each deployment.
Deployment Configuration
Configuration is read from hidden elements in index.html at
runtime.
| Element ID | Purpose | Default |
|---|---|---|
| sb-domain | SearchBlox server origin (e.g. https://search.company .com). Leave empty to use the same origin the plugin is served from. | window.location.origin |
| sb-collection | Default collection ID pre-selected on load | "" (none) |
| sb-collection-name | Display name for the default collection | "Knowledge Base" |
Example index.html snippet:
<input type="hidden" id="sb-domain" value="https://search.company.com" />
<input type="hidden" id="sb-collection" value="3" />
<input type="hidden" id="sb-collection-name" value="Product Docs" />
When sb-domain is empty, all API calls go to the current origin
(window.location.origin), so the plugin and SearchBlox can be co-hosted without any
extra configuration.
Routing & Navigation
The plugin uses React Router v6 BrowserRouter with an auto-detected basename, so it
works regardless of the folder name or nesting depth under the web server root.
Auto-basename detection: On startup, detectBasename() inspects
window.location.pathname and strips known route segments (entity, topic,
document, browse, graph, search) to infer the deployment prefix automatically.
| URL Example | Detected Basename |
|---|---|
| /plugins/kgwiki1/browse | /plugins/kgwiki1 |
| /my-wiki/entity/123 | /my-wiki |
| /browse | "" (root) |
Route table:
| Path | Page |
|---|---|
| / | Home |
| /search?q= | Search |
| /browse?tab= | Browse |
| /entity/:entityId | Entity detail |
| /document/:documentId | Document detail |
| /topic/:topicName | Topic detail |
| /graph | Graph Explorer |
All pages are lazy-loaded (code-split) with a spinner fallback.
Sidebar Navigation
The sidebar has three groups:
- Discover: Home, Search
- Browse: Entities, Topics, Relationships
- Visualize: Graph Explorer
Every navigation link automatically appends the active collection (?col=&cname=)
so the selected collection is never lost when switching pages.
.htaccess (Apache)
A public/.htaccess file is included with mod_rewrite rules to serve index.html for all
non-file paths, enabling full client-side routing on Apache servers.
Collection Management
The collection selector appears in the top header on every page.

How it works
- Dropdown is populated via GET /rest/v2/api/collections (fetched once,
cached 10 min). - On selection, the active collection is stored in two places simultaneously:
- Module-level store (collectionStore.ts) — read by API functions which
cannot access React context. - React context (CollectionContext) — read by UI components.
- All cached query data is immediately invalidated
(queryClient.invalidateQueries()), causing every visible section to re-fetch for
the new collection. - col and cname are written into the URL query string so the selection survives page
refreshes and can be bookmarked/shared.
Priority order for initial collection
- URL params ?col=&cname= (survives refresh / shared links)
- #sb-collection / #sb-collection-name hidden inputs (deployment default)
- Empty (no collection, dash shown on Home)
Clear
The dropdown has an × clear button. Clearing removes col/cname from the URL and sends all
subsequent API calls without a collection filter.
Pages
Home Page

Route: /
The landing page provides a dashboard overview of the knowledge graph.
| Card | Data Source | Click action |
|---|---|---|
| Collection | Active collection name or "–" | — |
| Entities | KGStats.entityCount | → Browse Entities |
| Relationships | KGStats.tripleCount | → Browse Relationships |
| Documents | KGStats.documentCount | → Browse Documents |
| Topics | KGStats.topicCount | → Browse Topics |
| Contexts | KGStats.contextCount | — |
Stats are fetched from GET /rest/v1/knowledge-graph/stats/.
Browse by Entity Type
A grid of clickable tiles, one per entity type (e.g. Person, Organization, Technology). Each tile
shows the type name and document count. Clicking navigates to the Browse → Entities tab
pre-filtered to that type.
Data from GET /rest/v1/knowledge-graph/entity-types.
Relationship Types
A tag cloud of all relationship predicate types with their triple counts (e.g. "Used For (142)").
Renders in batches of 20 with a Show more button. Predicate names are formatted via a
human-friendly label lookup (e.g. is_part_of → "Is Part Of").
Data from KGFacets.predicates via GET /rest/v1/knowledge-graph/facets.
Browse by Topic
A paginated tag cloud of knowledge graph topics. Loads 20 at a time from GET
/rest/v1/knowledge-graph/topics. Each topic tag is clickable and navigates to the Topic
detail page. Shows "X of Y topics" progress.
Search Page
Route: /search?q=
Performs a simultaneous search across entities and documents.

Search Bar
A large search input at the top of the page. Submitting a query updates the URL (?q=)
and triggers both search APIs.
Entities Section
- Calls GET
/rest/v1/knowledge-graph/entities/search?query=&limit=9
- Also calls GET
/rest/v1/knowledge-graph/entities/similar?entity=&limit=6
and
merges (deduped by id) - Rendered as an EntityGrid
Documents Section (Hybrid Search)
- Calls GET
/rest/v2/api/hybrid-search?query=&page=
&pagesize=&col=
- Initial load: page=1, pagesize=10
- Load more: page=2+, pagesize=20
- Results accumulate — clicking "Load more" appends the next page rather than replacing
- Each result shows: title (external link), document type badge, source URL, highlighted
snippet (with tags rendered) - Shows "Showing X of Y" counter and "All N results shown" when exhausted
Automatically derived from entity names and document topics in the current results, dedupedRelated Topics Section
and limited to 8. Each tag navigates to the Topic page.
Browse Page
Route: /browse?tab=<entities|topics|relationships>
A tabbed browser for exploring the full knowledge graph.
All active filters are persisted in the URL (tab, type, query, page, and collection), so the exact
view can be bookmarked or refreshed.
Entities Tab
- Filter sidebar (left, hidden when no entity types exist): text search input + Entity Type
radio filter. Selecting a type filters the grid. - Entity grid (main area): EntityGrid with server-side pagination (15 per page).
- Data from GET
/rest/v1/knowledge-graph/browse?type=&query=&offset=&
limit=15

Topics Tab
- Full-width card listing all topics from the knowledge graph as clickable tags.
- Client-side filter input shown only when topics exist (hidden if empty).
- Clicking a tag navigates to the Topic detail page.
- When no topics are found, a centered empty state ("No topics found.") is shown. When
the filter matches nothing, "No topics match your filter." is shown. - Tab label shows the count of loaded topics.

Relationships Tab
- Full-width card listing all relationship predicate types as tags with counts.
- Client-side filter input shown only when relationships exist.
- Human-friendly label display (e.g. developed_by → "Developed By").
- Empty states follow the same pattern as Topics.

Entity Page
Route: /entity/:entityId
Detailed view for a single knowledge graph entity
Header Card
| Field | Details |
|---|---|
| Entity type badge | Icon + type label (colour-coded) |
| Name | Canonical name in Title Case; original name shown below if different |
| Aliases | Up to 3 alternative names shown as tags |
| Mention count | Number of times the entity appears in the corpus |
| Confidence | Extraction confidence percentage |
| Description | Free-text summary or bio |
| Entity ID | Copyable raw ID |
Neighborhood Graph (right column)
A small interactive D3 graph showing the entity and its direct (1-hop) connections. Up to 15
neighbours. Clicking any node navigates to that entity's page. A "Full Graph" button opens the
entity's traversal in the Graph Explorer.
Data from GET
/rest/v1/knowledge-graph/traverse?entityId=&depth=1&limit=15.
Relationships Card
Two sub-tabs:
By Predicate — Triples are grouped by relationship type and direction:
- → Outgoing: This entity is the subject (e.g. "Company → uses → Technology")
- ← Incoming: This entity is the object (e.g. "Person → works for → This Company")
- Each group is collapsible (shows 5, toggle to show all)
- Related entity names link to their entity pages
All Triples — Ant Design table with columns: Subject / Predicate / Object / Confidence. Subject
and Object are links. Paginated (10 per page).
Data from GET /rest/v1/knowledge-graph/entities//triples?limit=50.
Related Entities
An EntityGrid of similar/related entities. Data from GET
/rest/v1/knowledge-graph/entities//related?limit=20.
Source Documents
List of documents that mention this entity. Shows document count in the card title. Each
document entry shows type, complexity, mention count, triple count, and up to 6 topics.
Data from GET /rest/v1/knowledge-graph/entities//documents?limit=20.
Document Page
Route: /document/:documentId
Rich view for a single document's knowledge graph context.
Header
Document title, type badge, complexity badge (colour-coded: Beginner=green,
Intermediate=blue, Advanced=orange, Expert=red), and a "View Source" button that opens the
original document URL in a new tab.
Summaries
Side-by-side panels:
- Executive Summary — high-level overview for non-technical readers
- Technical Summary — implementation/technical details
Key Takeaways & Action Items
Bulleted lists with distinct icons (✓ for takeaways, → for action items).
Metadata
Categorised tag rows: | Row | Content | |---|---| | Topics | Knowledge graph topics (clickable →
Topic page) | | Audience | Target personas (e.g. "Developer", "Manager") | | Roles | Job roles | |
Use Cases | Business use cases | | Industries | Industry verticals | | Prerequisites | Required
background knowledge |
Learning Path
A horizontal stepper showing where this document sits in a recommended learning sequence.
Step titles are clickable links to the corresponding document pages. Only shown when the path
has more than one step.
| Column | API EndPoint |
|---|---|
| Similar Documents | GET /recommend/similar/?limit= 5 |
| Prerequisites | GET /recommend/prerequisites/? limit=5 |
| Follow-up Reading | GET /recommend/follow-up/?limi t=5 |
Topic Page
Route: /topic/:topicName
Aggregated view of all content related to a topic.
- Documents — DocumentList of all documents tagged with the topic (via
browseDocuments({ topic, limit: 20 })). - Related Entities — EntityGrid of entities associated with the topic (GET
/rest/v1/knowledge-graph/topics//entities). - Related Topics — Computed from co-occurring topics across the topic's documents (top
12 by frequency). Each tag links to its own topic page.
Graph Page
Route: /graph
A full-screen, interactive force-directed graph visualisation of the entire knowledge graph (or a
filtered subset).

Left Control Panel
- Node Limit: Buttons for 10 / 50 / 100 / 250 / 500 nodes (default 50). Changes trigger a
re-fetch. - Entity Types filter: Checkbox list. "All" / "None" quick-toggle buttons. Only types
present in the current data are shown. - Stats: Live node and edge count for the current view.
- Interaction hints: Keyboard/mouse shortcut reference.
Graph Canvas
D3 force-directed simulation with:
- Node size scaled logarithmically by mention count (radius 8–20 px)
- Forces: Link distance 140, repulsion -400, centering, collision avoidance
- Zoom: Mouse wheel / pinch, range 0.05×–4×, auto-fits on load
- Edge labels: Hidden by default, revealed on hover
- Arrowheads indicate direction of relationship
Interactions
| Interaction | Action |
|---|---|
| Click node | Show detail overlay (name, type, mention count) |
| Double-click node | Navigate to Entity page |
| Right-click node | Expand connections |
| Drag node | Pin node position |
| Mouse wheel | Zoom |
| Click background | Pan |
Node Selection Overlay
Floating panel (top-right of canvas) showing the selected node's details with two buttons:
- "View Entity Page" — navigates to /entity/
- "Expand Connections" — lazily fetches the node's 1-hop traversal (depth=1,
limit=10) and merges new nodes and links into the graph without a full reload
Toggling an entity type hides/shows its nodes and also removes any edges where eitherEntity Type Filtering
endpoint is hidden.
API Integration
Base URLs
| API Base | URL |
|---|---|
| Knowledge Graph APIs | ${sbDomain}/rest/v1/knowledge-gra ph |
| Collections API | ${sbDomain}/rest/v2/api/collectio ns |
| Hybrid Search API | ${sbDomain}/rest/v2/api/hybrid-se arch |
| Drag node | Pin node position |
| Mouse wheel | Zoom |
| Click background | Pan |
When sb-domain is empty, sbDomain resolves to window.location.origin.
Knowledge Graph Endpoints
| EndPoint | Purpose |
|---|---|
| GET /stats/ | Global stats (entity/triple/document/topic counts) |
| GET /entity-types | List of entity types with counts |
| GET /entities/ | Single entity detail |
| GET /entities/search | Text search across entities |
| GET /browse | Paginated entity browser with type/query filters |
| GET /entities//related | Related entities |
| GET /entities/similar | Similar entities by name/embedding |
| GET /entities//triples | All triples for an entity |
| GET /entities//documents | Documents mentioning an entity |
| GET /facets | Topic, predicate, and entity type facets |
| GET /topics | Paginated topic list |
| GET /topics//entities | Entities associated with a topic |
| GET /contexts/by-topic | Document chunks for a topic |
| GET /documents//context | Full document context |
| GET /documents/browse | Filtered document browser |
| GET /recommend/similar/ | Similar document recommendations |
| GET /recommend/prerequisites/ | Prerequisite documents |
| GET /recommend/follow-up/ | Follow-up documents |
| GET /recommend/learning-path/ | Full learning path |
| GET /visualize | Full graph data for visualisation |
| GET /traverse | 1-hop neighbourhood traversal |
Response Shape Normalisation
All API functions defensively handle multiple response shapes to work with different SearchBlox,
Solr, and Elasticsearch backend versions:
- Arrays may be bare ([...]) or wrapped ({ results: [...] }, { docs: [...]
}, { items: [...] }, etc.) - Field names may be camelCase or snake_case (e.g. entityId / entity_id,
mentionCount / mention_count) - Hybrid search handles 8 distinct response shapes including Solr, Elasticsearch, and
SearchBlox native formats
Caching (TanStack React Query)
| Data type | Cache duration |
|---|---|
| Stats, entity types, facets | 10 minutes |
| Entity detail, triples, graph | 5 minutes |
| Search results, hybrid search | 2 minutes |
| Document browse | 2 minutes |
All caches are busted immediately when the active collection changes.
Components Reference
Layout
| Component | Purpose |
|---|---|
| WikiLayout | Outer shell: header (logo + collection selector) + sidebar + |
| Sidebar | Left navigation with group labels and active-state detection |
| Breadcrumb | Page breadcrumb trail, always starts with Home |
Graph
| Component | Purpose |
|---|---|
| FullGraph | Interactive full-screen D3 force-directed graph with zoom, drag, expand |
| MiniGraph | Compact embedded graph for EntityPage neighbourhood (320×240 default) |
Entity
| Component | Purpose |
|---|---|
| EntityCard | Clickable card showing entity name, type, mentions, description |
| EntityGrid | CSS grid of EntityCard components |
| EntityTypeIcon | Maps entity type string to an Ant Design icon |
| EntityDocumentList | List of documents mentioning an entity |
| RelationshipList | Groups and displays triples by predicate + direction |
Document
| Component | Purpose |
|---|---|
| DocumentCard | Clickable card: title, type, complexity, topics, score |
| DocumentList | Vertical list of DocumentCard components |
| ComplexityBadge | Colour-coded complexity level tag |
| LearningPath | Horizontal showing learning sequence |
| MetadataTags | Labelled row of tags (optionally navigable) |
Search
| Component | Purpose |
|---|---|
| SearchBar | Search input, navigates to /search?q= on submit |
| HybridSearchResultList | List of hybrid search result cards with highlight rendering |
Shared
| Component | Purpose |
|---|---|
| LoadingState | Unified loading/error/empty state wrapper |
| FacetPanel | Grouped radio/checkbox facet sidebar with overflow handling |
| Pagination | Ant Design pagination, only renders if total > pageSize |
Error & Empty States
LoadingState shows one of three states:
| Condition | Display |
|---|---|
| Loading | Centered |
| Network / service error | with WiFi icon + "Service unavailable. Please try again later." |
| Any other API error | with WiFi icon + "No results found." |
| Empty data | with custom description |
URL Parameter Reference
The plugin stores all significant UI state in URL parameters for shareability and
refresh-persistence.
| Parameter | Pages | Description |
|---|---|---|
| col | All | Active collection ID |
| cname | All | Active collection display name |
| q | Search, Browse | Search / filter query |
| tab | Browse | Active tab: entities, topics, relationships |
| type | Browse | Entity type filter |
| page | Browse | Current page number |
| persona | Browse | Document persona filter |
| complexity | Browse | Document complexity filter |
| docType | Browse | Document type filter |
| role | Browse | Document role filter |
| topic | Browse | Document topic filter |
Disabled / Hidden Features
The following features are fully implemented in code but hidden from the UI (commented out).
They can be re-enabled by uncommenting the relevant lines.
| Feature | Location | What it does |
|---|---|---|
| Documents Browse tab | BrowsePage.tsx | Paginated document browser with multi-facet filtering (persona, role, complexity, type, topic) |
| Documents nav item | Sidebar.tsx | "Documents" entry in the Browse sidebar group |
| Browse Documents By section | HomePage.tsx | Dashboard section for browsing documents by facets |
| Header search | WikiLayout.tsx | Global search input in the top header |
Predicate Label Dictionary
Human-readable labels are applied to all relationship predicate names. Known mappings
include:
| Raw predicate | Display label |
|---|---|
| is_part_of | Is Part Of |
| used_for | Used For |
| developed_by | Developed By |
| related_to | Related To |
| integrates_with | Integrates With |
| belongs_to | Belongs To |
| located_in | Located In |
| works_for | Works For |
| founded_by | Founded By |
| created_by | Created By |
| depends_on | Depends On |
| similar_to | Similar To |
| enables | Enables |
| requires | Requires |
| implements | Implements |
| extends | Extends |
| references | References |
Unknown predicates are auto-formatted: underscores replaced with spaces, each word
capitalised.
Build & Development
# Install dependencies
npm install
# Start dev server (https://localhost:9005, with Vite proxy to SearchBlox backend)
npm run dev
# Production build
npm run build
# Analyse bundle size
npm run analyze
Vite Dev Proxy
The Vite dev server proxies /rest and /searchblox paths to the SearchBlox backend
configured in index.html (sb-domain), so API calls work in development without CORS
issues.
Build Output (dist/)
| File | Description |
|---|---|
| build.[hash].js | App entry bundle |
| assets/vendor.[hash].js | All node_modules dependencies |
| assets/*.css | Merged stylesheet |
Hash-based filenames enable reliable cache-busting on each deployment.
Updated about 6 hours ago
