Appearance
Introduction
Welcome to the Antikythera library docs. The package connects a frontend to Antikythera's article, settings, file, font, and annotation APIs. It exports the Antikythera client plus the AntikytheraMenu and AntikytheraFooter custom elements. They can be used together or separately.
Antikythera provides the query and annotation lifecycle API between the Sanity/Nitro backend and your frontend.
AntikytheraMenu is a custom HTML element that renders the compact article sticker, expanded reading companion, downloads, related articles, About content, and annotation cards.
Access is managed through a private npm package. Framework projects can import it normally; plain HTML and Eleventy integrations copy the built browser files from node_modules rather than vendoring them.
Installation
The Antikythera library is a private scoped package on the npm registry.
Request an npm access token, configure it below, then install the current 2.1.0 release:
bash
bun add @antikythera/antikythera@latestIf Bun is unavailable, use pnpm add @antikythera/antikythera@latest.
Access Token Configuration
Local Config
To install this package locally, you must first add an .npmrc file to your project root. Your file must specify the registry and Access Token scope:
bash
@antikythera:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=<ACCESS_TOKEN>WARNING
Please make sure your .npmrc file is included in your .gitignore file as it will contain sensitive data.
Deployment Config
To make sure your package is installed on deployment, you must add an NPM_TOKEN environmental variable:
md
NPM_TOKEN=<ACCESS_TOKEN>Setting up
WARNING
The Antikythera client registers browser custom elements and scans the DOM, so instantiate it on the client side of your application.
Framework Recommendation
The Antikythera Component + API have been most extensively tested with React or Vue.
In your frontend code you can instantiate and access the Antikythera objects like this:
Vue/Nuxt
Details
vue
<script setup>
import { Antikythera, AntikytheraMenu } from '@antikythera/antikythera'
import '@antikythera/antikythera/fonts'
onMounted(async () => {
const antikythera = new Antikythera({ entry: 'example-entry' })
})
</script>React/Next
Details
jsx
import { Antikythera, AntikytheraMenu } from '@antikythera/antikythera'
import '@antikythera/antikythera/fonts'
export default function Home() {
let antikythera
useEffect(() => {
if (!antikythera) {
antikythera = new Antikythera({ entry: 'example-entry' })
}
}, [])
}Eleventy
Details
html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="./css/fonts.css" />
</head>
<body>
<script type="module">
import { Antikythera, AntikytheraMenu } from './js/antikythera.js'
document.addEventListener('DOMContentLoaded', async () => {
const antikythera = new Antikythera({ entry: 'example-entry' })
window.article = await antikythera.getEntry({ textStyle: 'html' })
document.getElementById('article-title').textContent = window.article?.entry?.title
document.getElementById('article-content').innerHTML =
window.article?.entry?.content
})
</script>
<div>
<antikythera-menu entry="example-entry"></antikythera-menu>
<aside>
<h1 id="article-title">ARTICLE TITLE</h1>
<div id="article-content">CONTENT</div>
</aside>
</div>
</body>
</html>WARNING
After installing dependencies, configure Eleventy to copy the library out of node_modules at build time (do not vendor a copy into your repo). The whole dist bundle is needed: the ES module lazily loads the analytics chunk relative to its own URL, so chunks/ must sit next to antikythera.js. The same mapping also publishes the typefaces: css/fonts.css references ../fonts/, so keep the two targets side by side.
js
module.exports = function (eleventyConfig) {
eleventyConfig.addPassthroughCopy({
"node_modules/@antikythera/antikythera/dist/antikythera.js": "js/antikythera.js",
"node_modules/@antikythera/antikythera/dist/chunks": "js/chunks",
"node_modules/@antikythera/antikythera/dist/css/fonts.css": "css/fonts.css",
"node_modules/@antikythera/antikythera/dist/fonts": "fonts"
})
}Vanilla JS/HTML
Details
html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="./node_modules/@antikythera/antikythera/dist/css/fonts.css" />
</head>
<script type="module">
import { Antikythera } from './node_modules/@antikythera/antikythera/dist/antikythera.js'
document.addEventListener('DOMContentLoaded', async () => {
const antikythera = new Antikythera({
entry: 'example-entry'
})
window.article = await antikythera.getEntry({ textStyle: 'html' })
document.getElementById('article-title').textContent = window.article?.entry?.title
document.getElementById('article-content').innerHTML = window.article?.entry?.content
// We call this manually since article content is fetched
// In the case where the article content is local this is not necessary (see docs for more info)
await antikythera.detectAnnotations()
})
</script>
<body>
<h1>Antikythera integration in a Vanilla JS project</h1>
<div>
<antikythera-menu entry="example-entry"></antikythera-menu>
<aside>
<h1 id="article-title">ARTICLE TITLE</h1>
<div id="article-content">CONTENT</div>
</aside>
</div>
</body>
</html>Svelte, Gatsby, Solidjs
tk. (2025)