Overview
The Knowledge Tooltip extension integrates with Wikidata to provide structured, factual information about entities (people, places, organizations, concepts). Wikidata serves as a knowledge base with machine-readable data.
Wikidata provides structured facts organized as properties and claims. The extension uses two APIs: the Search API to find entity IDs, and the Entity Data API to retrieve detailed information.
Features Using This API
Encyclopedia Tab : Enriches Wikipedia content with structured facts
Entity Recognition : Identifies proper nouns and concepts
Multi-language Facts : Returns data in the user’s preferred language with fallbacks
Structured Information : Birth dates, occupations, countries, populations, and more
Search Entities Endpoint
Searches Wikidata to find the best matching entity and returns its ID.
Endpoint
GET https://www.wikidata.org/w/api.php?action=wbsearchentities&search={term}&language={lang}&limit=1&format=json&origin=*
action
string
default: "wbsearchentities"
Wikidata API action for entity search
Search query (URL-encoded)
Language code for search and labels (en, ar, etc.)
Maximum number of results to return
CORS origin (required for cross-origin requests)
Implementation
From background.js:141-159:
async function searchWikidataEntity ( term , language ) {
const langCode = language === 'ar' ? 'ar' : 'en' ;
const url = `https://www.wikidata.org/w/api.php?action=wbsearchentities&search= ${ encodeURIComponent ( term ) } &language= ${ langCode } &limit=1&format=json&origin=*` ;
const response = await fetch ( url );
if ( ! response . ok ) {
throw new Error ( `HTTP ${ response . status } ` );
}
const data = await response . json ();
if ( data . search && data . search . length > 0 ) {
return data . search [ 0 ];
}
return null ;
}
Request Example
chrome . runtime . sendMessage ({
action: 'searchWikidata' ,
term: 'Albert Einstein' ,
language: 'en'
}, ( response ) => {
if ( response . success && response . data ) {
const entityId = response . data . id ;
console . log ( `Found entity: ${ entityId } ` );
}
});
Response Structure
Array of matching entities (limited to 1 by default) Wikidata entity ID (e.g., Q937, Q42)
Human-readable entity label
Short description of the entity
URL to the Wikidata entity page
Response Example
{
"search" : [
{
"id" : "Q937" ,
"label" : "Albert Einstein" ,
"description" : "German-born theoretical physicist (1879-1955)" ,
"url" : "https://www.wikidata.org/wiki/Q937"
}
]
}
Entity Data Endpoint
Retrieves detailed information about a specific Wikidata entity using its ID.
Endpoint
GET https://www.wikidata.org/wiki/Special:EntityData/{entityId}.json
Wikidata entity ID (e.g., Q937, Q42, Q30)
Implementation
From background.js:161-249:
async function fetchWikidataEntity ( entityId , language ) {
const url = `https://www.wikidata.org/wiki/Special:EntityData/ ${ entityId } .json` ;
const response = await fetch ( url );
if ( ! response . ok ) {
throw new Error ( `HTTP ${ response . status } ` );
}
const data = await response . json ();
const entity = data . entities [ entityId ];
if ( ! entity ) {
throw new Error ( 'Entity not found' );
}
const langCode = language === 'ar' ? 'ar' : 'en' ;
const fallbackLang = langCode === 'ar' ? 'en' : 'ar' ;
// Extract label and description with language fallback
const label = entity . labels ?.[ langCode ]?. value ||
entity . labels ?.[ fallbackLang ]?. value ||
entityId ;
const description = entity . descriptions ?.[ langCode ]?. value ||
entity . descriptions ?.[ fallbackLang ]?. value ||
'' ;
// Extract and process claims/properties
const claims = entity . claims || {};
const facts = [];
// ... (property extraction logic)
return { label , description , facts };
}
Request Example
chrome . runtime . sendMessage ({
action: 'fetchWikidataEntity' ,
entityId: 'Q937' ,
language: 'en'
}, ( response ) => {
if ( response . success ) {
console . log ( response . data . label );
console . log ( response . data . description );
response . data . facts . forEach ( fact => {
console . log ( ` ${ fact . label } : ${ fact . value } ` );
});
}
});
Processed Response Structure
The extension processes the raw Wikidata JSON into a simplified format:
Entity name in the requested language (with fallback)
Short description in the requested language (with fallback)
Array of extracted property-value pairs Human-readable property name (e.g., “Born”, “Occupation”, “Country”)
Formatted value(s) for the property
Processed Response Example
{
"label" : "Albert Einstein" ,
"description" : "German-born theoretical physicist" ,
"facts" : [
{ "label" : "Born" , "value" : "March 14, 1879" },
{ "label" : "Died" , "value" : "April 18, 1955" },
{ "label" : "Occupation" , "value" : "physicist, university teacher" },
{ "label" : "Country" , "value" : "Germany, United States" },
{ "label" : "Awards" , "value" : "Nobel Prize in Physics" }
]
}
Supported Properties
The extension extracts and displays specific Wikidata properties mapped to human-readable labels:
Person Properties
Property ID English Label Arabic Label Example Value P569Born تاريخ الميلاد ”March 14, 1879” P570Died تاريخ الوفاة ”April 18, 1955” P27Country الجنسية ”Germany” P106Occupation المهنة ”physicist” P69Education التعليم ”ETH Zurich” P26Spouse الزوج/ة ”Mileva Marić” P40Children الأبناء ”Hans Albert Einstein” P166Awards جوائز ”Nobel Prize in Physics” P800Notable work أعمال بارزة ”Theory of relativity”
Place Properties
Property ID English Label Arabic Label Example Value P17Country البلد ”United States” P1082Population عدد السكان ”8,336,817” P625Coordinates الإحداثيات ”40.7128, -74.0060” P36Capital العاصمة ”Washington, D.C.” P2046Area المساحة ”9,833,520 km²” P421Timezone المنطقة الزمنية ”UTC-5”
Organization Properties
Property ID English Label Arabic Label Example Value P571Founded تاريخ التأسيس ”April 1, 1976” P112Founded by المؤسس ”Steve Jobs, Steve Wozniak” P159Headquarters المقر ”Cupertino, California” P169CEO الرئيس التنفيذي ”Tim Cook” P452Industry القطاع ”Technology” P856Website الموقع الرسمي ”https://www.apple.com ”
The extension displays up to 3 values per property and processes up to ~30 different property types. See background.js:189-220 for the complete property mapping.
Data Type Processing
Wikidata values come in different data types that require specific formatting:
Time Values
From background.js:319-337:
case 'time' : {
const time = datavalue . value . time ;
// Parse +YYYY-MM-DDT00:00:00Z format
const match = time . match ( / ( [ +- ] \d + ) - ( \d {2} ) - ( \d {2} ) / );
if ( match ) {
const year = parseInt ( match [ 1 ]);
const month = parseInt ( match [ 2 ]);
const day = parseInt ( match [ 3 ]);
if ( month === 0 && day === 0 ) return ` ${ Math . abs ( year ) } ` ;
const date = new Date ( Math . abs ( year ), month - 1 , day );
const options = { year: 'numeric' , month: 'long' , day: 'numeric' };
try {
return date . toLocaleDateString ( langCode , options );
} catch {
return ` ${ day } / ${ month } / ${ Math . abs ( year ) } ` ;
}
}
return time;
}
Quantity Values
From background.js:338-345:
case 'quantity' : {
const amount = parseFloat ( datavalue . value . amount );
try {
return amount . toLocaleString ( langCode );
} catch {
return amount . toString ();
}
}
Coordinate Values
From background.js:350-354:
case 'globecoordinate' : {
const lat = datavalue . value . latitude . toFixed ( 4 );
const lon = datavalue . value . longitude . toFixed ( 4 );
return ` ${ lat } , ${ lon } ` ;
}
Other Data Types
Entity references (wikibase-entityid): Returns the entity ID (e.g., Q42)
Monolingual text (monolingualtext): Extracts the text value
Strings (string): Returns as-is
Language Fallback Strategy
Not all entities have labels, descriptions, or property values in all languages. The extension implements a fallback mechanism.
From background.js:178-184:
const langCode = language === 'ar' ? 'ar' : 'en' ;
const fallbackLang = langCode === 'ar' ? 'en' : 'ar' ;
const label = entity . labels ?.[ langCode ]?. value ||
entity . labels ?.[ fallbackLang ]?. value ||
entityId ;
const description = entity . descriptions ?.[ langCode ]?. value ||
entity . descriptions ?.[ fallbackLang ]?. value ||
'' ;
Fallback order:
Requested language (e.g., Arabic)
Opposite language (e.g., English)
Entity ID as last resort
Error Handling
From background.js:50-62:
if ( message . action === 'searchWikidata' ) {
searchWikidataEntity ( message . term , message . language )
. then ( data => sendResponse ({ success: true , data }))
. catch ( error => sendResponse ({ success: false , error: toErrMsg ( error ) }));
return true ;
}
if ( message . action === 'fetchWikidataEntity' ) {
fetchWikidataEntity ( message . entityId , message . language )
. then ( data => sendResponse ({ success: true , data }))
. catch ( error => sendResponse ({ success: false , error: toErrMsg ( error ) }));
return true ;
}
Common Error Scenarios
Error Cause Handling HTTP 404Entity ID doesn’t exist Return null, don’t display Wikidata section Entity not foundResponse missing entity data Throw error, caught by message handler No search resultsSearch returns empty array Return null from search function HTTP 500Wikidata server error Display error state in UI
Usage Flow
Typical workflow for fetching entity information:
// Step 1: Search for entity ID
chrome . runtime . sendMessage ({
action: 'searchWikidata' ,
term: 'Paris' ,
language: 'en'
}, ( searchResponse ) => {
if ( searchResponse . success && searchResponse . data ) {
const entityId = searchResponse . data . id ;
// Step 2: Fetch detailed entity data
chrome . runtime . sendMessage ({
action: 'fetchWikidataEntity' ,
entityId: entityId ,
language: 'en'
}, ( entityResponse ) => {
if ( entityResponse . success ) {
displayWikidataFacts ( entityResponse . data );
}
});
}
});
Rate Limits
Wikidata API rate limits:
200 requests/second for anonymous users
No authentication required
Consider caching entity data locally
Best Practices
Cache entity data : Store fetched entities by ID to avoid repeated requests
Batch entity lookups : If needing multiple entities, consider using the wbgetentities action
Minimize search calls : Use search results carefully; they’re more expensive than entity fetches
Raw Entity Data Structure
The raw Wikidata entity JSON is complex. Key sections:
{
"entities" : {
"Q937" : {
"id" : "Q937" ,
"labels" : {
"en" : { "language" : "en" , "value" : "Albert Einstein" },
"ar" : { "language" : "ar" , "value" : "ألبرت أينشتاين" }
},
"descriptions" : {
"en" : { "language" : "en" , "value" : "German-born theoretical physicist" }
},
"claims" : {
"P569" : [
{
"mainsnak" : {
"datavalue" : {
"type" : "time" ,
"value" : {
"time" : "+1879-03-14T00:00:00Z" ,
"timezone" : 0 ,
"precision" : 11
}
}
}
}
],
"P106" : [
{
"mainsnak" : {
"datavalue" : {
"type" : "wikibase-entityid" ,
"value" : { "id" : "Q169470" }
}
}
}
]
}
}
}
}