Skip to main content

VocabularyTable Component - Developer Guide

The VocabularyTable component displays controlled vocabularies in a professional, searchable format with multilingual support and CSV data loading capabilities.

Important Note on Imports

The VocabularyTable component is globally registered and available in all MDX files without import for JSX usage:

<VocabularyTable {...frontMatter} />

However, if you need to access static methods like generateTOC, you must import the component:

import { VocabularyTable } from '@ifla/theme';

export const toc = VocabularyTable.generateTOC(frontMatter);

Usage

The component is designed to work directly with Docusaurus front matter and supports global defaults from docusaurus.config.ts:

Global Defaults

The component uses defaults from customFields.vocabularyDefaults in docusaurus.config.ts:

// docusaurus.config.ts
const config = {
// ...other config
customFields: {
vocabularyDefaults: {
prefix: "isbdm",
startCounter: 1000,
uriStyle: "numeric",
caseStyle: "kebab-case",
showFilter: true,
filterPlaceholder: "Filter vocabulary terms...",
showTitle: false,
RDF: {
"rdf:type": ["skos:ConceptScheme"]
}
}
}
};

These defaults are used when the corresponding props are not provided in the front matter, reducing duplication across vocabulary pages.

---
vocabularyId: "1275"
title: ISBDM Extent of Unitary Structure value vocabulary
uri: http://iflastandards.info/ns/isbdm/values/1275
type: Vocabulary
description: This value vocabulary is a source of values for a has extent of unitary structure element.
scopeNote: The vocabulary does not cover the full scope of the element and may be extended with additional values.
isDefinedBy: http://iflastandards.info/ns/isbdm/values/1275
RDF:
skos:prefLabel:
en: ISBDM Extent of Unitary Structure value vocabulary
skos:definition:
en: This value vocabulary is a source of values for a has extent of unitary structure element.
values:
- value: term1
definition: Definition of first term
scopeNote: Additional notes about the first term
- value: term2
definition: Definition of second term
---

# {frontMatter.title}

<VocabularyTable {...frontMatter} />

Note how common properties like prefix, startCounter, uriStyle, caseStyle, showTitle, showFilter, and filterPlaceholder don't need to be specified in every file since they'll use the defaults from the site configuration.

Overriding Defaults

You can override any default value in your front matter:

---
vocabularyId: "special-vocab"
title: Special Vocabulary
prefix: "special" # Override the default "isbdm" prefix
uriStyle: "slug" # Override the default "numeric" style
caseStyle: "camelCase" # Override the default "kebab-case"
showFilter: false # Disable filtering
RDF:
values:
- value: "Term One"
definition: "Definition of first term"
---

Props

The component accepts the entire front matter structure:

PropTypeRequiredDescription
vocabularyIdstringYesUnique identifier for the vocabulary
titlestringNoThe title of the vocabulary
prefixstringNoNamespace prefix for URIs (default: 'isbdm')
uristringNoThe base URI of the vocabulary
typestringNoThe type of the vocabulary
descriptionstringNoThe main description of the vocabulary
scopeNotestringNoAdditional notes about the vocabulary's scope
isDefinedBystringNoURI that defines the vocabulary
RDFRDFMetadataNo*RDF metadata and vocabulary values (legacy format)
conceptsConceptProps[]No*Array of concepts (alternative to RDF.values)
startCounternumberNoStarting number for term IDs (default: 1000)
uriStyle'numeric' | 'slug'NoMethod for generating URIs (default: 'numeric')
caseStyleUriCaseStyleNoCase style for slug URIs (default: 'kebab-case')
showTitlebooleanNoWhether to display the title in the component (default: false)
showFilterbooleanNoWhether to display the filter input (default: true)
showURIsbooleanNoWhether to display URIs in the value column (default: true)
filterPlaceholderstringNoPlaceholder text for the filter input (default: 'Filter values...')

*Note: Either RDF.values or concepts must be provided, but not both. The concepts format is the newer, simpler format.

Page Title Handling

By default, the component doesn't display the title from the front matter (showTitle={false}). Instead, you should add the title as an H1 heading in your MDX file to avoid duplicate titles:

# {frontMatter.title}

<VocabularyTable {...frontMatter} />

If you need the component to display the title (for example, if it's used inside another component), you can set showTitle={true}.

Filter Functionality

The component includes a search filter above the table that allows users to quickly find terms by filtering on:

  • Term values
  • Definitions
  • Scope notes

The filter is case-insensitive and matches any part of the text in these fields. If no matches are found, a "No matching terms found" message is displayed.

Expandable Details

The component now includes an expandable details feature. When a concept has additional SKOS properties beyond the main three displayed columns (value, definition, scope note), a "+" button appears in the leftmost column. Clicking this button expands a details row that displays:

  • Notation - The concept's notation/code
  • Example - Usage examples
  • Change note - Notes about changes to the concept
  • History note - Historical information about the concept
  • Editorial note - Editorial guidance or notes

The expanded details provide a clean way to access additional metadata without cluttering the main table view.

You can customize the filter with these props:

  • showFilter: Set to false to hide the filter (default: true)
  • filterPlaceholder: Customize the placeholder text (default: 'Filter values...')

UriStyle Options

  • numeric: Generates URIs like prefix:vocabularyId#t1000
  • slug: Generates URIs like prefix:vocabularyId#term-name

CaseStyle Options (for slug URIs)

  • kebab-case: Words separated by hyphens (e.g., term-name)
  • snake_case: Words separated by underscores (e.g., term_name)
  • camelCase: First word lowercase, others capitalized (e.g., termName)
  • PascalCase: All words capitalized (e.g., TermName)

Data Interfaces

The newer, simpler format for defining concepts:

interface ConceptProps {
value: string; // Maps to skos:prefLabel
definition: string; // Maps to skos:definition
scopeNote?: string; // Maps to skos:scopeNote
notation?: string; // Maps to skos:notation
example?: string; // Maps to skos:example
changeNote?: string; // Maps to skos:changeNote
historyNote?: string; // Maps to skos:historyNote
editorialNote?: string; // Maps to skos:editorialNote
}

RDFMetadata Interface (Legacy)

The original format that embeds values within an RDF structure:

interface RDFMetadata {
'rdf:type'?: string[];
'skos:prefLabel'?: {
[lang: string]: string;
};
'skos:definition'?: {
[lang: string]: string;
};
'skos:scopeNote'?: {
[lang: string]: string;
};
values: ConceptProps[]; // Uses the same ConceptProps structure
}

TOCItem Interface

Used by the generateTOC static method:

interface TOCItem {
value: string;
id: string;
children: TOCItem[];
level: number; // Required by Docusaurus, defaults to 3
}

URL Fragment Navigation

Each term row has an HTML ID attribute matching the URI fragment, allowing direct access via URL fragments:

# For numeric style
https://yoursite.org/vocabulary-page#t1000

# For slug style
https://yoursite.org/vocabulary-page#activity-card

SKOS Relationships

The component automatically generates SKOS relationships for each concept:

  • rdf:type: Set to skos:Concept
  • skos:inScheme: Links to the vocabulary using prefix:vocabularyId
  • skos:topConceptOf: Links to the vocabulary (all concepts are top concepts by default)

These relationships are embedded in the component's data attributes for RDF extraction but are not directly displayed in the UI.

Using the generateTOC Method

The component provides a static generateTOC method for generating a table of contents from vocabulary data. This is particularly useful for glossaries where you want the terms to appear in the Docusaurus sidebar:

export const toc = VocabularyTable.generateTOC(frontMatter);

Examples

---
vocabularyId: "example"
title: "My Vocabulary"
description: "Example using the simpler concepts format"
concepts:
- value: "term one"
definition: "Definition of first term"
scopeNote: "Additional context for term one"
- value: "term two"
definition: "Definition of second term"
notation: "T2"
example: "Example usage of term two"
---

# {frontMatter.title}

<VocabularyTable {...frontMatter} />

Basic Usage with RDF Format (Legacy)

---
vocabularyId: "example"
title: "My Vocabulary"
RDF:
values: [
{
value: "term one",
definition: "Definition of first term"
},
{
value: "term two",
definition: "Definition of second term"
}
]
---

# {frontMatter.title}

<VocabularyTable {...frontMatter} />

Using Additional SKOS Properties

---
vocabularyId: "detailed-example"
title: "Vocabulary with Full SKOS Properties"
concepts:
- value: "aggregate"
definition: "A manifestation that embodies more than one discrete expression"
scopeNote: "Used for collections and compilations"
notation: "AGG"
example: "A book containing multiple novels"
changeNote: "Definition clarified in 2024"
historyNote: "Introduced in version 2.0"
editorialNote: "Consider relationship to collection concepts"
---

# {frontMatter.title}

<VocabularyTable {...frontMatter} />

In this example, a "+" button appears in the first column for the "aggregate" term. Clicking it reveals the additional SKOS properties in an expanded details section below the main row.

Without Filter

<VocabularyTable 
{...frontMatter}
showFilter={false}
/>

Without URIs (for glossaries)

For glossaries, you'll typically want to hide URIs but still show the table of contents:

---
vocabularyId: "glossary"
title: "Glossary"
description: "Glossary of terms used throughout the documentation"
showURIs: false
concepts: [
// your glossary terms...
]
---

# Glossary

<VocabularyTable {...frontMatter} />

// Export the toc to generate the right sidebar TOC from the glossary terms
export const toc = VocabularyTable.generateTOC(frontMatter);

Or when using the component directly:

<VocabularyTable 
{...frontMatter}
showURIs={false}
/>

With Custom Filter Placeholder

<VocabularyTable 
{...frontMatter}
filterPlaceholder="Search for terms..."
/>

With Component-Rendered Title

Component-Rendered Title

When showTitle is true, the component renders the title

Value
Definition
Scope note

example term
(ifla:example#t1000)

This is just an example

Numeric URIs (Default)

Using numeric URIs with startCounter=1000

Value
Definition
Scope note

term one
(ifla:example#t1000)

Definition of first term

term two
(ifla:example#t1001)

Definition of second term

Slug URIs

Using slug URIs with kebab-case

Value
Definition
Scope note

term one
(ifla:example#term-one)

Definition of first term

term two
(ifla:example#term-two)

Definition of second term

Without URIs (Example)

Example of a glossary with hidden URIs

Value
Definition
Scope note

aggregate

A manifestation that embodies more than one discrete expression.

dataset

An aggregation of metadata that describes instances of specific entities.

Each instance has a discrete description. A dataset may include instances of more than one type of entity.

Expandable Details (Live Example)

The following example demonstrates the expandable details feature. Notice the "+" button appears for terms that have additional SKOS properties:

Click the + button to see additional properties

Detail
Value
Definition
Scope note

monograph
(ifla:details-demo#t1000)

A resource that is complete in one part or intended to be completed within a finite number of parts.

Typically used for books and similar publications

serial
(ifla:details-demo#t1001)

A resource issued in successive parts, usually having numbering, that has no predetermined conclusion.

Includes periodicals, newspapers, annual reports, journals, etc.

integrating resource
(ifla:details-demo#t1002)

A resource that is added to or changed by means of updates that do not remain discrete but are integrated into the whole.