npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fsegurai/marked-extended-footnote

v17.0.0

Published

Extension for Marked.js that adds support for extended footnotes, allowing the creation of footnotes with custom formatting and behavior. It supports any Markdown rendering and can be customized to fit your needs.

Readme

An extension library for Marked.js to enhance Markdown rendering.

@fsegurai/marked-extended-footnote Extension for Marked.js that adds support for extended footnotes, allowing the creation of footnotes with custom formatting and behavior. It supports any Markdown rendering and can be customized to fit your needs.

🎯 Overview

The marked-extended-footnote extension brings comprehensive footnote and citation support to your Markdown documents. With automatic numbering, bidirectional linking, hover previews, and rich content support, it's perfect for academic papers, technical documentation, legal documents, and any content requiring detailed references or additional context.

✨ Key Features

  • 📝 Multiple Footnote Styles: Named ([^name]), numbered ([^1]), and inline (^[text]) footnotes
  • 🔢 Automatic Numbering: Sequential numbering regardless of reference order
  • 🔗 Bidirectional Linking: Click to jump between references and definitions
  • 👁️ Hover Previews: See footnote content on hover without scrolling
  • 📐 Flexible Placement: Bottom, section-based, or custom positioning
  • 🎨 Customizable Formatting: Multiple numbering styles (numeric, alphabetic, Roman, symbols)
  • 📱 Smooth Scrolling: Animated navigation with configurable offset
  • 🔄 Rich Content Support: Full Markdown in footnote definitions
  • Accessible: Semantic HTML with proper ARIA attributes
  • 🎛️ Highly Configurable: Extensive customization options
  • 🔧 Framework Agnostic: Works with React, Vue, Angular, Svelte, and vanilla JS
  • 💡 Smart References: Same footnote referenced multiple times handled automatically

🎪 Live Demo

Experience footnotes in action: View Demo


Table of contents

Installation

To add @fsegurai/marked-extended-footnote along with Marked.js to your package.json use the following commands.

bun install @fsegurai/marked-extended-footnote marked@^17 --save

Usage

Basic Usage

Import @fsegurai/marked-extended-footnote and apply it to your Marked instance as shown below.

Quick Start

Basic Syntax

Footnotes use [^identifier] for references and [^identifier]: content for definitions.

This statement needs a citation[^1].

[^1]: This is the footnote content.
import { marked } from 'marked';
import markedExtendedFootnote from '@fsegurai/marked-extended-footnote';

// or UMD script
// <script src="https://cdn.jsdelivr.net/npm/marked/lib/marked.umd.js"></script>
// <script src="https://cdn.jsdelivr.net/npm/@fsegurai/marked-extended-footnote/lib/index.umd.js"></script>

marked.use(markedExtendedFootnote());

### Installation

Install the package using your preferred package manager:

```bash
# Using Bun (recommended)
bun add @fsegurai/marked-extended-footnote

# Using npm
npm install @fsegurai/marked-extended-footnote

# Using yarn
yarn add @fsegurai/marked-extended-footnote

# Using pnpm
pnpm add @fsegurai/marked-extended-footnote

Basic Implementation

import { marked } from 'marked';
import markedExtendedFootnote from '@fsegurai/marked-extended-footnote';

// Import styles (required for functionality)
import '@fsegurai/marked-extended-footnote/styles/footnote.css';
// Optional: Import theme for styled appearance
import '@fsegurai/marked-extended-footnote/styles/footnote-theme.css';

// Register the extension
marked.use(markedExtendedFootnote());

// Your markdown content with footnotes
const markdown = `
# Research Paper

This statement needs a citation[^1]. Here's another fact[^important-note].

You can also use inline footnotes^[This is an inline footnote] for quick references.

## Multiple References

The same footnote can be referenced multiple times[^1]. Notice how it maintains 
the same number[^1] but tracks all reference locations.

## Footnote Definitions

[^1]: This is a basic footnote with simple text.

[^important-note]: This is a more complex footnote that can contain:

    - Multiple paragraphs
    - **Bold text** and *italic text*
    - \`code snippets\`
    - [Links](https://example.com)

    Even multiple paragraphs with proper indentation.
`;

// Parse and render
const html = marked.parse(markdown);
console.log(html);

Syntax & Usage

Basic Reference and Definition

Text with footnote[^1].

[^1]: Footnote content.

Named Footnotes

Use descriptive names for better organization:

Important concept[^key-concept] discussed here.

[^key-concept]: Named footnotes are easier to manage in long documents.

Inline Footnotes

For short, quick references:

Quick note^[Inline footnotes don't need separate definitions].

Multiple References

Reference the same footnote multiple times:

First reference[^study]. 
Second reference to same source[^study].
Third reference[^study].

[^study]: Smith, J. (2025). The Study. *Journal*, 10(2), 123-456.

Complex Content

Footnotes support full Markdown:

Advanced topic[^complex].

[^complex]: This footnote contains multiple elements:

    **Heading-like text**
    
    1. Ordered lists
    2. With multiple items
    
    - Unordered lists
    - Also supported
    
    \`\`\`javascript
    // Even code blocks!
    console.log("Full Markdown support");
    \`\`\`
    
    > Blockquotes work too
    
    And [links](https://example.com) of course.
    
    Remember: content must be indented under the footnote definition.

Footnotes are automatically numbered and linked bidirectionally – click a footnote reference to jump to the definition
and use the return link to go back. The extension supports **nested Markdown content** within footnote definitions.

### Styling Your Footnotes

This extension **does not automatically inject styles**. You must import the CSS or SCSS files manually (see [Importing Styles](#importing-styles)) to ensure proper styling and hover effects.

#### Generated HTML Structure

```html
<!-- In-text reference -->
<sup class="footnote-ref">
    <a href="#fn1" id="fnref1">[1]</a>
</sup>

<!-- Footnote list at bottom -->
<div class="footnotes">
    <hr>
    <ol>
        <li id="fn1">
            <p>Footnote content here.
                <a href="#fnref1" class="footnote-backref">↩</a>
            </p>
        </li>
    </ol>
</div>

CSS Classes Reference

| Class | Purpose | Element | |---------------------|------------------------------|-----------------| | .footnote-ref | Superscript reference marker | sup | | .footnote-ref a | Reference link | Link | | .footnotes | Footnotes container | Container div | | .footnotes hr | Separator line | Horizontal rule | | .footnotes ol | Numbered list | Ordered list | | .footnotes li | Individual footnote | List item | | .footnote-backref | Return to reference link | Link |

Complete Styling Example

/* In-text Reference */
.footnote-ref {
    font-size: 0.75em;
    line-height: 0;
    position: relative;
    vertical-align: baseline;
    top: -0.5em;
}

.footnote-ref a {
    color: #0066cc;
    text-decoration: none;
    font-weight: 600;
    padding: 0 2px;
    border-radius: 2px;
    transition: all 0.2s ease;
}

.footnote-ref a:hover {
    background: rgba(0, 102, 204, 0.1);
    text-decoration: underline;
}

.footnote-ref a:focus {
    outline: 2px solid #0066cc;
    outline-offset: 2px;
}

/* Footnotes Section */
.footnotes {
    margin-top: 3rem;
    padding-top: 2rem;
    border-top: 2px solid #e0e0e0;
    font-size: 0.875rem;
    color: #666;
}

.footnotes hr {
    display: none; /* Hide default hr, using border-top instead */
}

.footnotes ol {
    padding-left: 1.5rem;
    margin: 0;
}

.footnotes li {
    margin-bottom: 1rem;
    line-height: 1.6;
}

.footnotes li:last-child {
    margin-bottom: 0;
}

.footnotes li p {
    margin: 0.5rem 0;
}

.footnotes li p:first-child {
    margin-top: 0;
}

.footnotes li p:last-child {
    margin-bottom: 0;
}

/* Back Reference Link */
.footnote-backref {
    margin-left: 0.5rem;
    font-size: 1.1em;
    text-decoration: none;
    color: #0066cc;
    font-weight: normal;
    transition: all 0.2s ease;
}

.footnote-backref:hover {
    transform: translateX(-2px);
    color: #0052a3;
}

.footnote-backref::before {
    content: " ";
}

/* Nested Content in Footnotes */
.footnotes code {
    padding: 0.2em 0.4em;
    background: rgba(0, 0, 0, 0.05);
    border-radius: 3px;
    font-size: 0.9em;
}

.footnotes a:not(.footnote-backref) {
    color: #0066cc;
    text-decoration: underline;
}

.footnotes ul,
.footnotes ol {
    margin: 0.5rem 0;
}

.footnotes blockquote {
    border-left: 3px solid #e0e0e0;
    padding-left: 1rem;
    margin: 0.5rem 0;
    font-style: italic;
}

Dark Mode Support

/* Light theme */
body.light .footnote-ref a {
    color: #0066cc;
}

body.light .footnotes {
    border-top-color: #e0e0e0;
    color: #666;
}

body.light .footnote-backref {
    color: #0066cc;
}

/* Dark theme */
body.dark .footnote-ref a {
    color: #58a6ff;
}

body.dark .footnote-ref a:hover {
    background: rgba(88, 166, 255, 0.1);
}

body.dark .footnotes {
    border-top-color: #444c56;
    color: #8b949e;
}

body.dark .footnote-backref {
    color: #58a6ff;
}

body.dark .footnote-backref:hover {
    color: #79b8ff;
}

body.dark .footnotes code {
    background: rgba(255, 255, 255, 0.1);
}

body.dark .footnotes blockquote {
    border-left-color: #444c56;
}

Variant: Sidebar Footnotes

/* Position footnotes in a sidebar on larger screens */
@media (min-width: 1200px) {
    .content-with-footnotes {
        display: grid;
        grid-template-columns: 1fr 300px;
        gap: 3rem;
    }

    .footnotes {
        position: sticky;
        top: 2rem;
        margin-top: 0;
        border-top: none;
        padding-top: 0;
        font-size: 0.8125rem;
    }

    .footnotes::before {
        content: "Footnotes";
        font-weight: 700;
        font-size: 0.875rem;
        display: block;
        margin-bottom: 1rem;
        color: #333;
    }
}

Variant: Tooltip Footnotes

/* Show footnote content on hover (requires JavaScript) */
.footnote-ref {
    position: relative;
}

.footnote-ref .footnote-tooltip {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    background: #333;
    color: white;
    padding: 0.5rem 0.75rem;
    border-radius: 4px;
    font-size: 0.75rem;
    white-space: nowrap;
    max-width: 300px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
    margin-bottom: 0.5rem;
    z-index: 100;
}

.footnote-ref:hover .footnote-tooltip {
    opacity: 1;
}

.footnote-tooltip::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 6px solid transparent;
    border-top-color: #333;
}

Print Styles

@media print {
    .footnote-ref a {
        color: #000;
        text-decoration: none;
    }

    .footnotes {
        page-break-before: always;
        border-top: 2px solid #000;
        color: #000;
    }

    .footnote-backref {
        display: none;
    }

    /* Ensure footnotes print on same page if possible */
    .footnotes li {
        page-break-inside: avoid;
    }
}

Accessibility Enhancements

/* Screen reader friendly */
.footnote-ref a[aria-label]::after {
    content: " (footnote " attr(aria-label) ")";
    position: absolute;
    left: -9999px;
}

/* High contrast mode */
@media (prefers-contrast: high) {
    .footnote-ref a {
        border: 1px solid currentColor;
        padding: 0 4px;
    }

    .footnotes {
        border-top-width: 3px;
    }
}

Check the demo to see footnotes with various styling options.

Footnote Syntax

Basic Footnotes

This text has a footnote[^1].

[^1]: This is the footnote content.

Named Footnotes

Important concept[^key-concept] explained here.

[^key-concept]: Use descriptive names for better organization.

Inline Footnotes

Quick reference^[Inline footnotes are convenient for short notes].

Complex Footnote Content

Advanced topic[^complex].

[^complex]: This footnote contains:

    1. Multiple paragraphs
    2. **Formatted text**
    3. Code blocks:
       
       \`\`\`javascript
       console.log("Footnotes can contain code!");
       \`\`\`
    
    4. [External links](https://example.com)
    
    All content must be properly indented under the footnote definition.

Reference Styles

The extension supports multiple footnote numbering and formatting styles:

  • Numeric (default): [1], [2], [3], ...
  • Alphabetic: [a], [b], [c], ... or [A], [B], [C], ...
  • Roman: [i], [ii], [iii], ... or [I], [II], [III], ...
  • Symbol: [*, †, ‡, §, ¶, ...] for traditional academic style
  • Custom: Define your own formatting pattern

Configuration Options

The marked-extended-footnote extension accepts the following configuration options:

  • footnoteClass: CSS class for footnote containers. Defaults to 'marked-extended-footnote'.
  • referenceClass: CSS class for footnote references in text. Defaults to 'footnote-ref'.
  • definitionClass: CSS class for footnote definitions. Defaults to 'footnote-def'.
  • backrefClass: CSS class for back-reference links. Defaults to 'footnote-backref'.
  • numberingStyle: Numbering style ('numeric', 'alpha', 'roman', 'symbol', 'custom'). Defaults to 'numeric'.
  • placement: Where to place footnotes ('bottom', 'section', 'inline'). Defaults to 'bottom'.
  • separator: HTML separator between document and footnotes. Defaults to <hr class="footnotes-sep">.
  • backrefText: Text for back-reference links. Defaults to '↩'.
  • customFormat: Function to customize footnote number formatting. For advanced use.
  • template: Custom HTML template for footnote structure. Defaults to built-in template.

Note: For styling, import CSS/SCSS files manually (see Importing Styles).

Advanced Examples

Academic Paper with Citations

# The Impact of Climate Change on Arctic Ecosystems

Climate change has significantly impacted Arctic ecosystems over the past decades[^ipcc2021]. The warming trend in the
Arctic is occurring at twice the global average rate, a phenomenon known as Arctic amplification[^serreze2011].

## Temperature Changes

Recent studies show that Arctic temperatures have increased by 2-3°C since 1960[^box2019]. This warming has led to:

1. Reduced sea ice extent[^stroeve2012]
2. Permafrost degradation[^biskaborn2019]
3. Changes in wildlife migration patterns[^post2013]

## Species Impact

The polar bear (*Ursus maritimus*) population has been particularly affected[^stirling2012]. Their primary habitat, sea
ice, has decreased by approximately 13% per decade since
1979^[Based on satellite observations from the National Snow and Ice Data Center].

## References

[^ipcc2021]: IPCC, 2021: Climate Change 2021: The Physical Science Basis. Contribution of Working Group I to the Sixth
Assessment Report of the Intergovernmental Panel on Climate Change. Cambridge University Press.

[^serreze2011]: Serreze, M.C., & Barry, R.G. (2011). Processes and impacts of Arctic amplification: A research
synthesis. *Global and Planetary Change*, 77(1-2), 85-96.

[^box2019]: Box, J.E., et al. (2019). Key indicators of Arctic climate change: 1971–2017. *Environmental Research
Letters*, 14(4), 045010.

    This comprehensive study analyzed multiple climate indicators including
    - Surface air temperature
    - Sea ice extent
    - Greenland ice sheet mass balance
    - Snow cover duration
    
    The data clearly shows accelerating change across all indicators.

[^stroeve2012]: Stroeve, J., & Notz, D. (2012). Changing state of Arctic sea ice across all seasons. *Environmental
Research Letters*, 7(4), 034009.

[^biskaborn2019]: Biskaborn, B.K., et al. (2019). Permafrost is warming at a global scale. *Nature Communications*, 10(
1), 1-11.

[^post2013]: Post, E., et al. (2013). Ecological consequences of sea-ice decline. *Science*, 341(6145), 519-524.

[^stirling2012]: Stirling, I., & Derocher, A.E. (2012). Effects of climate warming on polar bears: a review of the
evidence. *Global Change Biology*, 18(9), 2694-2706.

Technical Documentation

# API Authentication Guide

## OAuth 2.0 Implementation

Our API uses OAuth 2.0 for authentication[^oauth2]. The implementation follows RFC 6749[^rfc6749] with PKCE
extension[^rfc7636] for enhanced security.

### Authorization Flow

1. **Client Registration**: Register your application[^registration] to obtain credentials
2. **Authorization Request**: Redirect users to our authorization server[^authz-endpoint]
3. **Authorization Grant**: Users approve the requested permissions[^scopes]
4. **Access Token**: Exchange authorization code for access token[^token-exchange]

### Security Considerations

Always use HTTPS for all OAuth flows[^security-best-practices]. Never expose client secrets in browser-based
applications^[Use the implicit flow or authorization code flow with PKCE for SPAs].

## Code Examples

### JavaScript Implementation

\`\`\`javascript
// Authorization URL construction
const authUrl = new URL('https://auth.example.com/oauth/authorize');
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('client_id', clientId);
authUrl.searchParams.append('scope', 'read-write');
authUrl.searchParams.append('state', generateRandomState());
\`\`\`

### Token Exchange

\`\`\`javascript
const response = await fetch('https://auth.example.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code: authorizationCode,
client_id: clientId,
client_secret: clientSecret
})
});
\`\`\`

## References

[^oauth2]: Hardt, D. (2012). *The OAuth 2.0 Authorization Framework*. RFC 6749. Internet Engineering Task Force.

[^rfc6749]: Available at: https://tools.ietf.org/html/rfc6749

[^rfc7636]: Sakimura, N., et al. (2015). *Proof Key for Code Exchange by OAuth Public Clients*. RFC 7636.

    PKCE (Proof Key for Code Exchange) adds a layer of security to OAuth 2.0 flows, particularly important for:
    - Mobile applications
    - Single-page applications (SPAs)
    - Any public client that cannot securely store secrets

[^registration]: Client registration can be done through our developer portal at https://developers.example.com

[^authz-endpoint]: Authorization endpoint: `https://auth.example.com/oauth/authorize`

[^scopes]: Available scopes include: `read`, `write`, `admin`, `billing`. See our [scope documentation] for details.

[^token-exchange]: Token endpoint: `https://auth.example.com/oauth/token`

[^security-best-practices]: For comprehensive security guidelines, see the OAuth 2.0 Security Best Current Practice
document (draft-ietf-oauth-security-topics).

Configuration Examples

// Basic academic-style footnotes
marked.use(markedExtendedFootnote({
    numberingStyle: 'numeric',
    placement: 'bottom'
}));

// Traditional academic with symbols
marked.use(markedExtendedFootnote({
    numberingStyle: 'symbol',
    backrefText: '↩︎',
    footnoteClass: 'academic-footnotes'
}));

// Custom formatting for legal documents
marked.use(markedExtendedFootnote({
    numberingStyle: 'custom',
    customFormat: (num) => `(${num})`,
    separator: '<div class="footnotes-separator"></div>',
    template: customLegalTemplate
}));

// Section-based footnotes for long documents
marked.use(markedExtendedFootnote({
    placement: 'section',
    numberingStyle: 'alpha',
    footnoteClass: 'section-footnotes'
}));

Enhanced Configuration Options

The extension accepts comprehensive configuration options:

marked.use(markedExtendedFootnote({
  prefixId: 'fnref-',
  description: 'Footnotes',
  refMarkers: false,
  backrefSymbol: '↩',
  backrefLinks: true,
  placeholderText: '[footnotes]',
  labelFormat: (id, number) => number,
  smoothScroll: true,
  scrollOffset: 80,
  hoverPreview: true,
  hoverPreviewMaxLength: 200
}));

Configuration Options Reference

| Option | Type | Default | Description | |-------------------------|------------|----------------|-------------------------------------------------------| | prefixId | string | 'fnref-' | Prefix for footnote IDs in HTML | | description | string | 'Footnotes' | Accessibility description for footnote section | | refMarkers | boolean | false | Show reference markers in brackets (e.g., [1]) | | backrefSymbol | string | '↩' | Symbol used for back-reference links | | backrefLinks | boolean | true | Include back-reference links in footnotes | | placeholderText | string | '[footnotes]'| Text to use as placeholder for custom positioning | | labelFormat | function | Returns number | Function to format footnote label/number | | smoothScroll | boolean | true | Enable smooth scrolling when clicking footnote links | | scrollOffset | number | 80 | Scroll offset in pixels (for fixed headers) | | hoverPreview | boolean | true | Show footnote preview on hover | | hoverPreviewMaxLength | number | 200 | Maximum characters in hover preview |

Configuration Examples

Academic Style (Numeric)

marked.use(markedExtendedFootnote({
  refMarkers: true,        // Show [1], [2], etc.
  backrefSymbol: '↩︎',
  smoothScroll: true,
  scrollOffset: 100        // Account for fixed header
}));

Legal Document Style

marked.use(markedExtendedFootnote({
  labelFormat: (id, number) => `(${number})`,  // Show (1), (2), etc.
  refMarkers: false,
  backrefSymbol: '⮐',
  prefixId: 'note-'
}));

Custom Placeholder Position

marked.use(markedExtendedFootnote({
  placeholderText: '[references]'  // Use custom placeholder
}));

// In markdown:
// ## References
// [references]  ← Footnotes appear here instead of at bottom

Disable Hover Previews

marked.use(markedExtendedFootnote({
  hoverPreview: false  // Disable hover tooltips
}));

Custom Label Formatting

// Roman numerals
marked.use(markedExtendedFootnote({
  labelFormat: (id, number) => {
    const romanNumerals = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x'];
    return romanNumerals[number - 1] || number;
  }
}));

// Alphabetic
marked.use(markedExtendedFootnote({
  labelFormat: (id, number) => {
    return String.fromCharCode(96 + number);  // a, b, c, etc.
  }
}));

// Symbols
marked.use(markedExtendedFootnote({
  labelFormat: (id, number) => {
    const symbols = ['*', '†', '‡', '§', '¶', '#'];
    return symbols[number - 1] || number;
  }
}));

Accessibility Enhanced

marked.use(markedExtendedFootnote({
  description: 'References and Citations',
  refMarkers: true,
  scrollOffset: 120,
  smoothScroll: true
}));

Best Practices

1. Use Descriptive Identifiers

<!-- Good: Descriptive IDs -->
[^smith2025]: Smith, J. (2025). Research Paper.
[^api-security]: API Security Best Practices.
[^performance-note]: Performance considerations.

<!-- Avoid: Generic numbers only -->
[^1]: Some reference.
[^2]: Another reference.

2. Maintain Consistent Formatting

<!-- Good: Consistent citation format -->
[^1]: Author, A. (Year). Title. *Journal*, Volume(Issue), Pages.
[^2]: Author, B. (Year). Title. *Journal*, Volume(Issue), Pages.

<!-- Avoid: Inconsistent formatting -->
[^1]: Author, A. 2025. Title. Journal, Vol. 10, pp. 123-456.
[^2]: B. Author "Title" (2025) Journal 10:123-456

3. Keep Footnote Content Relevant

<!-- Good: Concise, relevant info -->
[^source]: Smith (2025), p. 42.

<!-- Avoid: Excessive tangential content -->
[^source]: Smith wrote this in 2025 on page 42, although some argue 
that the study methodology could be improved and there are several 
competing theories...  (continues for 500 words)

4. Group Related Footnotes

## Method

Our approach follows established protocols[^method1][^method2].

[^method1]: Jones et al. (2023). Standard Protocol.
[^method2]: Smith (2024). Protocol Refinements.

5. Use Inline Footnotes Sparingly

<!-- Good: Short clarification -->
The API rate limit^[100 requests per minute] applies to all endpoints.

<!-- Avoid: Long inline footnotes -->
The system architecture^[Our system uses a microservices architecture 
with Docker containers, Kubernetes orchestration, Redis caching, 
PostgreSQL databases...] is highly scalable.

<!-- Better: Use definition-style footnote for long content -->
The system architecture[^architecture] is highly scalable.

[^architecture]: Our system uses a microservices architecture with 
    Docker containers, Kubernetes orchestration, Redis caching, and 
    PostgreSQL databases for data persistence.

6. Properly Indent Multi-paragraph Footnotes

[^complex]: First paragraph of footnote.

    Second paragraph must be indented with 4 spaces.
    
    Third paragraph also indented.
    
    - Lists must be indented
    - To align properly

7. Place Footnotes Near First Use

<!-- Good: Definitions near first use -->
# Introduction

Key concept[^concept] is fundamental.

[^concept]: Definition of the key concept.

## Next Section

Another topic[^topic] is discussed.

[^topic]: Explanation of the topic.

Use Cases

1. Academic Research Papers

# The Impact of Artificial Intelligence on Healthcare

## Abstract

Recent advances in artificial intelligence (AI) have transformed healthcare 
delivery and patient outcomes[^gpt-healthcare]. Machine learning algorithms 
can now detect diseases with accuracy comparable to human experts[^radiology-ai].

## Introduction

The application of AI in healthcare has grown exponentially since 2015[^growth-stats]. 
Notable applications include:

- Medical imaging analysis[^imaging]
- Drug discovery[^drug-discovery]
- Personalized treatment plans[^personalization]
- Predictive analytics[^predictive]

## Methodology

Our study analyzed 50,000 patient records using a neural network architecture 
based on transformer models[^transformers]. The dataset was sourced from three 
major hospitals[^data-source].

### Ethical Considerations

All procedures followed institutional review board guidelines[^irb]. Patient data 
was anonymized according to HIPAA regulations[^hipaa].

## Results

The AI model achieved 94.3% accuracy in disease detection[^results], significantly 
outperforming traditional methods^[Traditional methods achieved 87.1% accuracy 
in our control group].

## Discussion

These findings align with previous research[^meta-analysis] but show improved 
performance metrics. However, limitations include potential bias in training 
data[^bias-concerns].

## References

[^gpt-healthcare]: Johnson, M., et al. (2024). "GPT Models in Healthcare: A 
    Comprehensive Review." *Journal of Medical AI*, 15(3), 234-267.
    
    This seminal paper reviews 300+ studies on language models in healthcare,
    covering:
    - Clinical documentation
    - Diagnostic assistance
    - Patient communication
    - Medical education

[^radiology-ai]: Chen, Y. & Park, S. (2025). "Deep Learning in Radiology: 
    Current State and Future Directions." *Radiology*, 298(1), 11-25.

[^growth-stats]: Smith, A. (2023). *Healthcare AI Market Analysis*. 
    TechResearch Inc.
    
    Market grew from $2.1B (2015) to $45.2B (2023), CAGR of 43.7%.

[^imaging]: Liu, X., et al. (2024). "CNN-based Medical Image Analysis." 
    *Medical Imaging*, 43(7), 891-908.

[^drug-discovery]: Kumar, R. (2025). "AI-Accelerated Drug Discovery: From 
    Months to Days." *Nature Medicine*, 31(2), 156-163.

[^personalization]: Anderson, K., et al. (2024). "Precision Medicine Through 
    AI." *Lancet Digital Health*, 6(4), e234-e245.

[^predictive]: Zhang, W. & Davis, T. (2025). "Predictive Analytics in ICU." 
    *Critical Care Medicine*, 53(1), 45-58.

[^transformers]: Vaswani, A., et al. (2017). "Attention Is All You Need." 
    *NeurIPS*.

[^data-source]: Data collected from:
    - Massachusetts General Hospital (n=20,000)
    - Johns Hopkins Hospital (n=18,000)
    - Mayo Clinic (n=12,000)
    
    Collection period: January 2022 - December 2024.

[^irb]: Approved by institutional review board, protocol #2024-0158.

[^hipaa]: All procedures compliant with HIPAA Privacy Rule (45 CFR § 164.508).

[^results]: 95% CI: 93.8-94.8%, p < 0.001 vs. control.

[^meta-analysis]: Brown, J., et al. (2024). "Meta-Analysis of AI Diagnostic 
    Tools." *JAMA*, 331(8), 672-689.

[^bias-concerns]: Thompson, L. (2025). "Addressing Bias in Medical AI." 
    *AI Ethics Journal*, 3(1), 12-28.

2. Technical Documentation

# API Reference Guide v2.0

## Authentication

All API requests require authentication[^auth-required]. We support two 
authentication methods:

1. **API Keys**[^api-keys]: For server-to-server communication
2. **OAuth 2.0**[^oauth]: For user-delegated access

### API Key Authentication

Include your API key in the request header:

\`\`\`http
GET /api/v2/users
Authorization: Bearer YOUR_API_KEY
\`\`\`

**Security Note**: Never expose API keys in client-side code[^security-best-practice].

### Rate Limiting

Rate limits vary by plan[^rate-limits]:

| Plan       | Requests/min | Requests/day |
|------------|--------------|--------------|
| Free       | 60           | 1,000        |
| Developer  | 600          | 100,000      |
| Business   | 6,000        | 1,000,000    |
| Enterprise | Custom       | Custom       |

Exceeding limits returns HTTP 429[^http-429].

## Endpoints

### GET /api/v2/users

Retrieves user information[^users-endpoint].

**Parameters:**

- `limit`: Maximum results (default: 10, max: 100)[^pagination]
- `offset`: Pagination offset[^pagination]
- `sort`: Sort field[^sorting]

**Response:**

\`\`\`json
{
  "data": [...],
  "meta": {
    "total": 1000,
    "limit": 10,
    "offset": 0
  }
}
\`\`\`

### Error Handling

All errors follow RFC 7807[^rfc7807] Problem Details format:

\`\`\`json
{
  "type": "https://api.example.com/errors/rate-limit",
  "title": "Rate Limit Exceeded",
  "status": 429,
  "detail": "Too many requests. Try again in 60 seconds.",
  "instance": "/api/v2/users"
}
\`\`\`

## SDKs and Libraries

Official SDKs are available for:

- **JavaScript/TypeScript**: \`@example/api-client\`[^js-sdk]
- **Python**: \`example-api\`[^python-sdk]
- **Ruby**: \`example_api\`[^ruby-sdk]
- **Go**: \`github.com/example/api-go\`[^go-sdk]

## Changelog

[^auth-required]: Authentication is required for all endpoints except 
    \`/health\` and \`/docs\`.

[^api-keys]: API keys can be generated in your dashboard at 
    https://dashboard.example.com/api-keys

[^oauth]: OAuth implementation follows RFC 6749 with PKCE extension (RFC 7636).

[^security-best-practice]: Store API keys in environment variables or secure 
    secret management systems. Never commit keys to version control.

[^rate-limits]: Rate limits reset every minute. Contact sales for 
    Enterprise custom limits.

[^http-429]: HTTP 429 responses include \`Retry-After\` header indicating 
    seconds until rate limit resets.

[^users-endpoint]: Requires \`users:read\` scope for OAuth authentication.

[^pagination]: Standard pagination using limit/offset. For large datasets, 
    consider cursor-based pagination using \`GET /api/v2/users/cursor\`.

[^sorting]: Valid sort fields: \`created_at\`, \`updated_at\`, \`name\`, 
    \`email\`. Prefix with \`-\` for descending order (e.g., \`-created_at\`).

[^rfc7807]: RFC 7807: Problem Details for HTTP APIs. 
    Available at: https://tools.ietf.org/html/rfc7807

[^js-sdk]: JavaScript SDK documentation: https://docs.example.com/sdk/js
    
    Installation: \`npm install @example/api-client\`

[^python-sdk]: Python SDK documentation: https://docs.example.com/sdk/python
    
    Installation: \`pip install example-api\`

[^ruby-sdk]: Ruby SDK documentation: https://docs.example.com/sdk/ruby
    
    Installation: \`gem install example_api\`

[^go-sdk]: Go SDK documentation: https://docs.example.com/sdk/go
    
    Installation: \`go get github.com/example/api-go\`

3. Legal Documents

# Software License Agreement

## 1. Grant of License

Subject to the terms and conditions of this Agreement[^agreement-def], Licensor 
hereby grants to Licensee a limited, non-exclusive, non-transferable license[^license-scope] 
to use the Software[^software-def].

## 2. Restrictions

Licensee shall not:

(a) Modify or create derivative works[^derivative-def];
(b) Reverse engineer or decompile[^reverse-eng];
(c) Remove proprietary notices[^notices];
(d) Sublicense or transfer rights[^transfer].

## 3. Intellectual Property

All intellectual property rights[^ip-rights] in the Software remain the exclusive 
property of Licensor. No title or ownership rights are transferred[^no-transfer].

## 4. Warranty Disclaimer

THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND[^warranty-disclaimer]. 
LICENSOR DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED[^implied-warranties], INCLUDING 
BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY[^merchantability] AND FITNESS 
FOR A PARTICULAR PURPOSE[^fitness].

## 5. Limitation of Liability

IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY DAMAGES[^damages-cap] EXCEEDING 
THE AMOUNT PAID BY LICENSEE UNDER THIS AGREEMENT[^liability-limit].

## 6. Governing Law

This Agreement shall be governed by the laws of [Jurisdiction][^jurisdiction] 
without regard to conflicts of law principles[^choice-of-law].

## Definitions

[^agreement-def]: "Agreement" means this Software License Agreement including 
    all exhibits, schedules, and amendments executed by both parties.

[^license-scope]: License is limited to:
    - Internal business operations only
    - Maximum of 50 concurrent users
    - Single production deployment
    - Non-commercial use
    
    For expanded rights, contact [email protected]

[^software-def]: "Software" means the computer programs and associated 
    documentation, including all updates and modifications provided by Licensor.

[^derivative-def]: "Derivative works" includes any work based upon the Software, 
    such as revisions, modifications, translations, abridgments, condensations, 
    expansions, or any form in which the Software may be recast, transformed, 
    or adapted.

[^reverse-eng]: Reverse engineering is prohibited except to the extent permitted 
    by applicable law notwithstanding this limitation. See 17 U.S.C. § 1201(f).

[^notices]: Proprietary notices include copyright notices, trademark symbols, 
    patent notices, and confidentiality legends.

[^transfer]: Assignment or transfer requires prior written consent from Licensor, 
    such consent not to be unreasonably withheld.

[^ip-rights]: Intellectual property rights include copyrights, patents, 
    trademarks, trade secrets, and all other proprietary rights, whether 
    registered or unregistered, in all jurisdictions worldwide.

[^no-transfer]: This is a license agreement, not a sale. Licensee acquires 
    only the right to use the Software subject to terms herein.

[^warranty-disclaimer]: Disclaimer complies with U.C.C. § 2-316. Consult with 
    legal counsel regarding enforceability in your jurisdiction.

[^implied-warranties]: Implied warranties include those arising from course of 
    dealing, usage of trade, or performance (U.C.C. § 2-314, § 2-315).

[^merchantability]: Warranty of merchantability means the software would be 
    suitable for ordinary purposes for which such goods are used (U.C.C. § 2-314).

[^fitness]: Warranty of fitness for particular purpose applies when seller has 
    reason to know buyer's particular purpose and buyer relies on seller's 
    skill or judgment (U.C.C. § 2-315).

[^damages-cap]: "Damages" includes direct, indirect, incidental, special, 
    consequential, and punitive damages, including but not limited to:
    - Lost profits
    - Lost data
    - Business interruption
    - Cost of substitute goods or services

[^liability-limit]: Total liability shall not exceed the greater of (i) amounts 
    paid by Licensee in the 12 months preceding the claim, or (ii) $500 USD.

[^jurisdiction]: [To be completed by parties]

[^choice-of-law]: Choice of law clause excludes application of United Nations 
    Convention on Contracts for the International Sale of Goods (CISG).

Troubleshooting

Footnotes Not Appearing

Problem: Footnote references show but definitions don't appear at bottom.

Solutions:

  1. Import CSS files:
import '@fsegurai/marked-extended-footnote/styles/footnote.css';
  1. Check definition syntax:
<!-- Correct -->
[^1]: Footnote content.

<!-- Wrong -->
[^1] Footnote content.  <!-- ❌ Missing colon -->
  1. Verify indentation for multi-line content:
[^1]: First line of footnote.

    Second paragraph must be indented with 4 spaces.

Broken Links Between References and Definitions

Problem: Clicking footnote reference doesn't navigate to definition.

Solutions:

  1. Check for duplicate IDs:
<!-- Avoid duplicate identifiers -->
[^1]: First footnote.
[^1]: This will cause conflicts!  <!-- ❌ Duplicate -->
  1. Verify smooth scroll configuration:
marked.use(markedExtendedFootnote({
  smoothScroll: true,
  scrollOffset: 80  // Adjust for fixed headers
}));

Hover Preview Not Showing

Problem: No preview appears when hovering over footnote references.

Solutions:

  1. Enable hover preview:
marked.use(markedExtendedFootnote({
  hoverPreview: true  // Default is true
}));
  1. Check CSS:
/* Ensure hover styles are not overridden */
.footnote-ref .footnote-tooltip {
  z-index: 1000;  /* High z-index to appear above content */
}

Formatting Issues in Footnote Content

Problem: Markdown formatting not rendering in footnotes.

Solutions:

  1. Proper indentation:
[^complex]: First paragraph.

    Second paragraph with **formatting**.
    
    - List items
    - Must be indented
    
    \`\`\`
    Code blocks also indented
    \`\`\`
  1. Check for special characters:
<!-- Escape special characters if needed -->
[^note]: Use \\[ and \\] to show literal brackets.

Custom Numbering Not Working

Problem: Custom label format function not applied.

Solution:

// Ensure function returns string or number
marked.use(markedExtendedFootnote({
  labelFormat: (id, number) => {
    // Must return a value
    return `Note ${number}`;  // ✅
    // Don't just modify without returning
  }
}));

Framework Integration

React Integration

// FootnoteMarkdown.tsx
import { marked } from 'marked';
import markedExtendedFootnote from '@fsegurai/marked-extended-footnote';
import '@fsegurai/marked-extended-footnote/styles/footnote.css';
import '@fsegurai/marked-extended-footnote/styles/footnote-theme.css';
import { useEffect, useState } from 'react';

// Configure marked
marked.use(markedExtendedFootnote({
  smoothScroll: true,
  scrollOffset: 80,
  hoverPreview: true,
  refMarkers: true
}));

interface Props {
  content: string;
  enableHoverPreview?: boolean;
}

export function FootnoteMarkdown({ content, enableHoverPreview = true }: Props) {
  const [html, setHtml] = useState('');
  
  useEffect(() => {
    // Reconfigure based on props
    marked.use(markedExtendedFootnote({
      hoverPreview: enableHoverPreview,
      smoothScroll: true,
      scrollOffset: 80
    }));
    
    const parsed = marked.parse(content);
    setHtml(parsed);
  }, [content, enableHoverPreview]);
  
  return (
    <article 
      className="markdown-with-footnotes"
      dangerouslySetInnerHTML={{ __html: html }} 
    />
  );
}

// Usage:
// <FootnoteMarkdown content={paper} enableHoverPreview={true} />

Vue 3 Integration

<script setup lang="ts">
import { marked } from 'marked';
import markedExtendedFootnote from '@fsegurai/marked-extended-footnote';
import '@fsegurai/marked-extended-footnote/styles/footnote.css';
import '@fsegurai/marked-extended-footnote/styles/footnote-theme.css';
import { computed, watch } from 'vue';

marked.use(markedExtendedFootnote({
  smoothScroll: true,
  scrollOffset: 80,
  hoverPreview: true
}));

interface Props {
  content: string;
  scrollOffset?: number;
  hoverPreview?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  scrollOffset: 80,
  hoverPreview: true
});

const html = computed(() => {
  marked.use(markedExtendedFootnote({
    smoothScroll: true,
    scrollOffset: props.scrollOffset,
    hoverPreview: props.hoverPreview
  }));
  return marked.parse(props.content);
});

watch([() => props.scrollOffset, () => props.hoverPreview], () => {
  console.log('Footnote config updated');
});
</script>

<template>
  <article class="markdown-content" v-html="html" />
</template>

Angular Integration

// footnote-markdown.component.ts
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { marked } from 'marked';
import markedExtendedFootnote from '@fsegurai/marked-extended-footnote';

marked.use(markedExtendedFootnote({
  smoothScroll: true,
  scrollOffset: 80,
  hoverPreview: true
}));

@Component({
  selector: 'app-footnote-markdown',
  template: \`<article [innerHTML]="parsedContent"></article>\`,
  styleUrls: [
    '../node_modules/@fsegurai/marked-extended-footnote/styles/footnote.css',
    '../node_modules/@fsegurai/marked-extended-footnote/styles/footnote-theme.css'
  ]
})
export class FootnoteMarkdownComponent implements OnChanges {
  @Input() content: string = '';
  @Input() scrollOffset: number = 80;
  @Input() hoverPreview: boolean = true;
  parsedContent: SafeHtml = '';

  constructor(private sanitizer: DomSanitizer) {}

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['content'] || changes['scrollOffset'] || changes['hoverPreview']) {
      marked.use(markedExtendedFootnote({
        smoothScroll: true,
        scrollOffset: this.scrollOffset,
        hoverPreview: this.hoverPreview
      }));
      
      const html = marked.parse(this.content);
      this.parsedContent = this.sanitizer.bypassSecurityTrustHtml(html);
    }
  }
}

Performance Tips

  1. Minimize Footnote Count: Keep footnote references reasonable (< 100 per document)
  2. Optimize Hover Preview Length: Shorter previews load faster
  3. Use Lazy Loading: For very long documents, consider lazy loading footnote section
  4. Disable Smooth Scroll on Mobile: Can improve performance on slower devices
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);

marked.use(markedExtendedFootnote({
  smoothScroll: !isMobile,  // Disable on mobile
  hoverPreview: !isMobile   // Disable on mobile
}));

Contributing

Found a bug or have a feature request? Please open an issue on GitHub.

Related Resources

Available Extensions

| Extension | Package | Version | Description | |-------------|--------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------|----------------------------------------------------------------------| | All - Bundle | @fsegurai/marked-extended-bundle | npm | Includes all extensions in a single package for easy integration | | Accordion | @fsegurai/marked-extended-accordion | npm | Add collapsible accordion sections to your markdown | | Alert | @fsegurai/marked-extended-alert | npm | Create styled alert boxes for important information | | Comments | @fsegurai/marked-extended-comments | npm | Add comment sections with author and timestamp metadata | | Embeds | @fsegurai/marked-extended-embeds | npm | Easily embed content from various platforms (YouTube, Twitter, etc.) | | Footnote | @fsegurai/marked-extended-footnote | npm | Add footnotes with automatic numbering | | Kanban | @fsegurai/marked-extended-kanban | npm | Create kanban boards with customizable columns and cards | | Lists | @fsegurai/marked-extended-lists | npm | Enhanced list formatting options | | Slide | @fsegurai/marked-extended-slide | npm | Create slide decks directly from markdown content | | Spoiler | @fsegurai/marked-extended-spoiler | npm | Hide content behind spoiler tags | | Tables | @fsegurai/marked-extended-tables | npm | Advanced table formatting with cell spanning | | Tabs | @fsegurai/marked-extended-tabs | npm | Create tabbed content sections | | Timeline | @fsegurai/marked-extended-timeline | npm | Display content in an interactive timeline format | | Typographic | @fsegurai/marked-extended-typographic | npm | Improve typography with smart quotes, dashes, and more |

Demo Application

To see all extensions in action, check out the [DEMO].

To set up the demo locally, follow the next steps:

git clone https://github.com/fsegurai/marked-extensions.git
bun install
bun start

This will serve the application locally at http://[::1]:8000.

License

Licensed under MIT.