diff --git a/blocksuite/affine/components/src/rich-text/all-extensions.ts b/blocksuite/affine/components/src/rich-text/all-extensions.ts
index deff7d00ee519..a0213db48630d 100644
--- a/blocksuite/affine/components/src/rich-text/all-extensions.ts
+++ b/blocksuite/affine/components/src/rich-text/all-extensions.ts
@@ -6,6 +6,7 @@ import {
   BoldInlineSpecExtension,
   CodeInlineSpecExtension,
   ColorInlineSpecExtension,
+  FootNoteInlineSpecExtension,
   InlineAdapterExtensions,
   InlineSpecExtensions,
   ItalicInlineSpecExtension,
@@ -31,6 +32,7 @@ export const DefaultInlineManagerExtension = InlineManagerExtension({
     LatexInlineSpecExtension.identifier,
     ReferenceInlineSpecExtension.identifier,
     LinkInlineSpecExtension.identifier,
+    FootNoteInlineSpecExtension.identifier,
   ],
 });
 
diff --git a/blocksuite/affine/components/src/rich-text/effects.ts b/blocksuite/affine/components/src/rich-text/effects.ts
index 64a44e761da09..0f2a7aeefb385 100644
--- a/blocksuite/affine/components/src/rich-text/effects.ts
+++ b/blocksuite/affine/components/src/rich-text/effects.ts
@@ -16,8 +16,14 @@ import type {
   toggleTextStyleCommand,
   toggleUnderline,
 } from './format/text-style.js';
-import { AffineLink, AffineReference } from './inline/index.js';
+import {
+  AffineFootnoteNode,
+  AffineLink,
+  AffineReference,
+} from './inline/index.js';
 import { AffineText } from './inline/presets/nodes/affine-text.js';
+import { FootNotePopup } from './inline/presets/nodes/footnote-node/footnote-popup.js';
+import { FootNotePopupChip } from './inline/presets/nodes/footnote-node/footnote-popup-chip.js';
 import { LatexEditorMenu } from './inline/presets/nodes/latex-node/latex-editor-menu.js';
 import { LatexEditorUnit } from './inline/presets/nodes/latex-node/latex-editor-unit.js';
 import { AffineLatexNode } from './inline/presets/nodes/latex-node/latex-node.js';
@@ -37,12 +43,18 @@ export function effects() {
   customElements.define('reference-popup', ReferencePopup);
   customElements.define('reference-alias-popup', ReferenceAliasPopup);
   customElements.define('affine-reference', AffineReference);
+  customElements.define('affine-footnote-node', AffineFootnoteNode);
+  customElements.define('footnote-popup', FootNotePopup);
+  customElements.define('footnote-popup-chip', FootNotePopupChip);
 }
 
 declare global {
   interface HTMLElementTagNameMap {
     'affine-latex-node': AffineLatexNode;
     'affine-reference': AffineReference;
+    'affine-footnote-node': AffineFootnoteNode;
+    'footnote-popup': FootNotePopup;
+    'footnote-popup-chip': FootNotePopupChip;
     'affine-link': AffineLink;
     'affine-text': AffineText;
     'rich-text': RichText;
diff --git a/blocksuite/affine/components/src/rich-text/inline/presets/affine-inline-specs.ts b/blocksuite/affine/components/src/rich-text/inline/presets/affine-inline-specs.ts
index 04518ea7853f0..fe957b0638b0f 100644
--- a/blocksuite/affine/components/src/rich-text/inline/presets/affine-inline-specs.ts
+++ b/blocksuite/affine/components/src/rich-text/inline/presets/affine-inline-specs.ts
@@ -1,4 +1,4 @@
-import { ReferenceInfoSchema } from '@blocksuite/affine-model';
+import { FootNoteSchema, ReferenceInfoSchema } from '@blocksuite/affine-model';
 import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
 import { StdIdentifier } from '@blocksuite/block-std';
 import type { InlineEditor, InlineRootElement } from '@blocksuite/inline';
@@ -6,6 +6,7 @@ import { html } from 'lit';
 import { z } from 'zod';
 
 import { InlineSpecExtension } from '../../extension/index.js';
+import { FootNoteNodeConfigIdentifier } from './nodes/footnote-node/footnote-config.js';
 import {
   ReferenceNodeConfigIdentifier,
   ReferenceNodeConfigProvider,
@@ -178,6 +179,30 @@ export const LatexEditorUnitSpecExtension = InlineSpecExtension({
   },
 });
 
+export const FootNoteInlineSpecExtension = InlineSpecExtension(
+  'footnote',
+  provider => {
+    const std = provider.get(StdIdentifier);
+    const config =
+      provider.getOptional(FootNoteNodeConfigIdentifier) ?? undefined;
+    return {
+      name: 'footnote',
+      schema: FootNoteSchema.optional().nullable().catch(undefined),
+      match: delta => {
+        return !!delta.attributes?.footnote;
+      },
+      renderer: ({ delta }) => {
+        return html`<affine-footnote-node
+          .delta=${delta}
+          .std=${std}
+          .config=${config}
+        ></affine-footnote-node>`;
+      },
+      embed: true,
+    };
+  }
+);
+
 export const InlineSpecExtensions = [
   BoldInlineSpecExtension,
   ItalicInlineSpecExtension,
@@ -190,4 +215,5 @@ export const InlineSpecExtensions = [
   ReferenceInlineSpecExtension,
   LinkInlineSpecExtension,
   LatexEditorUnitSpecExtension,
+  FootNoteInlineSpecExtension,
 ];
diff --git a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-config.ts b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-config.ts
new file mode 100644
index 0000000000000..2bc4c7fd11f2c
--- /dev/null
+++ b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-config.ts
@@ -0,0 +1,93 @@
+import type { FootNote } from '@blocksuite/affine-model';
+import { type BlockStdScope, StdIdentifier } from '@blocksuite/block-std';
+import { createIdentifier } from '@blocksuite/global/di';
+import type { ExtensionType } from '@blocksuite/store';
+import type { TemplateResult } from 'lit';
+
+type FootNoteNodeRenderer = (
+  footnote: FootNote,
+  std: BlockStdScope
+) => TemplateResult<1>;
+
+type FootNotePopupRenderer = (
+  footnote: FootNote,
+  std: BlockStdScope,
+  abortController: AbortController
+) => TemplateResult<1>;
+
+export interface FootNoteNodeConfig {
+  customNodeRenderer?: FootNoteNodeRenderer;
+  customPopupRenderer?: FootNotePopupRenderer;
+  interactive?: boolean;
+  hidePopup?: boolean;
+}
+
+export class FootNoteNodeConfigProvider {
+  private _customNodeRenderer?: FootNoteNodeRenderer;
+  private _customPopupRenderer?: FootNotePopupRenderer;
+  private _hidePopup: boolean;
+  private _interactive: boolean;
+
+  get customNodeRenderer() {
+    return this._customNodeRenderer;
+  }
+
+  get customPopupRenderer() {
+    return this._customPopupRenderer;
+  }
+
+  get doc() {
+    return this.std.store;
+  }
+
+  get hidePopup() {
+    return this._hidePopup;
+  }
+
+  get interactive() {
+    return this._interactive;
+  }
+
+  constructor(
+    config: FootNoteNodeConfig,
+    readonly std: BlockStdScope
+  ) {
+    this._customNodeRenderer = config.customNodeRenderer;
+    this._customPopupRenderer = config.customPopupRenderer;
+    this._hidePopup = config.hidePopup ?? false;
+    this._interactive = config.interactive ?? true;
+  }
+
+  setCustomNodeRenderer(renderer: FootNoteNodeRenderer) {
+    this._customNodeRenderer = renderer;
+  }
+
+  setCustomPopupRenderer(renderer: FootNotePopupRenderer) {
+    this._customPopupRenderer = renderer;
+  }
+
+  setHidePopup(hidePopup: boolean) {
+    this._hidePopup = hidePopup;
+  }
+
+  setInteractive(interactive: boolean) {
+    this._interactive = interactive;
+  }
+}
+
+export const FootNoteNodeConfigIdentifier =
+  createIdentifier<FootNoteNodeConfigProvider>('AffineFootNoteNodeConfig');
+
+export function FootNoteNodeConfigExtension(
+  config: FootNoteNodeConfig
+): ExtensionType {
+  return {
+    setup: di => {
+      di.addImpl(
+        FootNoteNodeConfigIdentifier,
+        provider =>
+          new FootNoteNodeConfigProvider(config, provider.get(StdIdentifier))
+      );
+    },
+  };
+}
diff --git a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-node.ts b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-node.ts
new file mode 100644
index 0000000000000..865acd4cba523
--- /dev/null
+++ b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-node.ts
@@ -0,0 +1,167 @@
+import type { FootNote } from '@blocksuite/affine-model';
+import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
+import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
+import {
+  BlockSelection,
+  type BlockStdScope,
+  ShadowlessElement,
+  TextSelection,
+} from '@blocksuite/block-std';
+import { WithDisposable } from '@blocksuite/global/utils';
+import {
+  type DeltaInsert,
+  INLINE_ROOT_ATTR,
+  type InlineRootElement,
+  ZERO_WIDTH_NON_JOINER,
+  ZERO_WIDTH_SPACE,
+} from '@blocksuite/inline';
+import { baseTheme } from '@toeverything/theme';
+import { css, html, nothing, unsafeCSS } from 'lit';
+import { property } from 'lit/decorators.js';
+import { ref } from 'lit-html/directives/ref.js';
+
+import { HoverController } from '../../../../../hover/controller';
+import type { FootNoteNodeConfigProvider } from './footnote-config';
+
+export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
+  static override styles = css`
+    .footnote-node {
+      padding: 0 2px;
+      user-select: none;
+      cursor: pointer;
+    }
+
+    .footnote-content-default {
+      display: inline-block;
+      background: ${unsafeCSSVarV2('button/primary')};
+      color: ${unsafeCSSVarV2('button/pureWhiteText')};
+      width: 14px;
+      height: 14px;
+      line-height: 14px;
+      font-size: 10px;
+      font-weight: 400;
+      border-radius: 50%;
+      text-align: center;
+      text-overflow: ellipsis;
+      font-family: ${unsafeCSS(baseTheme.fontSansFamily)};
+    }
+  `;
+
+  get customNodeRenderer() {
+    return this.config?.customNodeRenderer;
+  }
+
+  get customPopupRenderer() {
+    return this.config?.customPopupRenderer;
+  }
+
+  get interactive() {
+    return this.config?.interactive;
+  }
+
+  get hidePopup() {
+    return this.config?.hidePopup;
+  }
+
+  get inlineEditor() {
+    const inlineRoot = this.closest<InlineRootElement<AffineTextAttributes>>(
+      `[${INLINE_ROOT_ATTR}]`
+    );
+    return inlineRoot?.inlineEditor;
+  }
+
+  get selfInlineRange() {
+    const selfInlineRange = this.inlineEditor?.getInlineRangeFromElement(this);
+    return selfInlineRange;
+  }
+
+  private readonly _FootNoteDefaultContent = (footnote: FootNote) => {
+    return html`<span class="footnote-content-default"
+      >${footnote.label}</span
+    >`;
+  };
+
+  private readonly _FootNotePopup = (
+    footnote: FootNote,
+    abortController: AbortController
+  ) => {
+    return this.customPopupRenderer
+      ? this.customPopupRenderer(footnote, this.std, abortController)
+      : html`<footnote-popup
+          .footnote=${footnote}
+          .std=${this.std}
+          .abortController=${abortController}
+        ></footnote-popup>`;
+  };
+
+  private readonly _whenHover: HoverController = new HoverController(
+    this,
+    ({ abortController }) => {
+      const footnote = this.delta.attributes?.footnote;
+      if (!footnote) return null;
+
+      if (
+        this.config?.hidePopup ||
+        !this.selfInlineRange ||
+        !this.inlineEditor
+      ) {
+        return null;
+      }
+
+      const selection = this.std?.selection;
+      if (!selection) {
+        return null;
+      }
+      const textSelection = selection.find(TextSelection);
+      if (!!textSelection && !textSelection.isCollapsed()) {
+        return null;
+      }
+
+      const blockSelections = selection.filter(BlockSelection);
+      if (blockSelections.length) {
+        return null;
+      }
+
+      return {
+        template: this._FootNotePopup(footnote, abortController),
+        container: this,
+        computePosition: {
+          referenceElement: this,
+          placement: 'top',
+          autoUpdate: true,
+        },
+      };
+    },
+    { enterDelay: 500 }
+  );
+
+  override render() {
+    const attributes = this.delta.attributes;
+    const footnote = attributes?.footnote;
+    if (!footnote) {
+      return nothing;
+    }
+
+    const node = this.customNodeRenderer
+      ? this.customNodeRenderer(footnote, this.std)
+      : this._FootNoteDefaultContent(footnote);
+
+    return html`<span
+      ${this.hidePopup ? '' : ref(this._whenHover.setReference)}
+      class="footnote-node"
+      >${node}<v-text .str=${ZERO_WIDTH_NON_JOINER}></v-text
+    ></span>`;
+  }
+
+  @property({ attribute: false })
+  accessor config: FootNoteNodeConfigProvider | undefined = undefined;
+
+  @property({ type: Object })
+  accessor delta: DeltaInsert<AffineTextAttributes> = {
+    insert: ZERO_WIDTH_SPACE,
+    attributes: {},
+  };
+
+  @property({ attribute: false })
+  accessor std!: BlockStdScope;
+}
diff --git a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-popup-chip.ts b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-popup-chip.ts
new file mode 100644
index 0000000000000..66193f7c27fa2
--- /dev/null
+++ b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-popup-chip.ts
@@ -0,0 +1,89 @@
+import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
+import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
+import { property } from 'lit/decorators.js';
+
+export class FootNotePopupChip extends LitElement {
+  static override styles = css`
+    .popup-chip-container {
+      display: flex;
+      border-radius: 4px;
+      max-width: 173px;
+      height: 24px;
+      padding: 2px 4px;
+      align-items: center;
+      gap: 4px;
+      box-sizing: border-box;
+      cursor: default;
+    }
+
+    .prefix-icon,
+    .suffix-icon {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 16px;
+      height: 16px;
+      color: ${unsafeCSSVarV2('icon/primary')};
+      border-radius: 4px;
+
+      svg {
+        width: 16px;
+        height: 16px;
+      }
+    }
+
+    .suffix-icon:hover {
+      background-color: ${unsafeCSSVarV2('layer/background/hoverOverlay')};
+      cursor: pointer;
+    }
+
+    .popup-chip-label {
+      flex: 1;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+      text-align: left;
+      height: 20px;
+      line-height: 20px;
+      color: ${unsafeCSSVarV2('text/primary')};
+      font-size: 12px;
+      font-weight: 400;
+    }
+  `;
+
+  override render() {
+    return html`
+      <div class="popup-chip-container" @click=${this.onClick}>
+        ${this.prefixIcon
+          ? html`<div class="prefix-icon" @click=${this.onPrefixClick}>
+              ${this.prefixIcon}
+            </div>`
+          : nothing}
+        <div class="popup-chip-label">${this.label}</div>
+        ${this.suffixIcon
+          ? html`<div class="suffix-icon" @click=${this.onSuffixClick}>
+              ${this.suffixIcon}
+            </div>`
+          : nothing}
+      </div>
+    `;
+  }
+
+  @property({ attribute: false })
+  accessor prefixIcon: TemplateResult | undefined = undefined;
+
+  @property({ attribute: false })
+  accessor label: string = '';
+
+  @property({ attribute: false })
+  accessor suffixIcon: TemplateResult | undefined = undefined;
+
+  @property({ attribute: false })
+  accessor onClick: (() => void) | undefined = undefined;
+
+  @property({ attribute: false })
+  accessor onPrefixClick: (() => void) | undefined = undefined;
+
+  @property({ attribute: false })
+  accessor onSuffixClick: (() => void) | undefined = undefined;
+}
diff --git a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-popup.ts b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-popup.ts
new file mode 100644
index 0000000000000..e929b67531c44
--- /dev/null
+++ b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/footnote-node/footnote-popup.ts
@@ -0,0 +1,126 @@
+import type { FootNote } from '@blocksuite/affine-model';
+import { DocDisplayMetaProvider } from '@blocksuite/affine-shared/services';
+import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
+import type { BlockStdScope } from '@blocksuite/block-std';
+import { WithDisposable } from '@blocksuite/global/utils';
+import { DualLinkIcon, LinkIcon } from '@blocksuite/icons/lit';
+import { css, html, LitElement, type TemplateResult } from 'lit';
+import { property } from 'lit/decorators.js';
+
+import { getAttachmentFileIcons } from '../../../../../icons';
+import { RefNodeSlotsProvider } from '../../../../extension/ref-node-slots';
+
+export class FootNotePopup extends WithDisposable(LitElement) {
+  static override styles = css`
+    .footnote-popup-container {
+      border-radius: 4px;
+      box-shadow: ${unsafeCSSVar('overlayPanelShadow')};
+      border-radius: 4px;
+      background-color: ${unsafeCSSVarV2('layer/background/primary')};
+      border: 0.5px solid ${unsafeCSSVarV2('layer/insideBorder/border')};
+    }
+  `;
+
+  private readonly _prefixIcon = () => {
+    const referenceType = this.footnote.reference.type;
+    if (referenceType === 'doc') {
+      const docId = this.footnote.reference.docId;
+      if (!docId) {
+        return undefined;
+      }
+      return this.std.get(DocDisplayMetaProvider).icon(docId).value;
+    } else if (referenceType === 'attachment') {
+      const fileType = this.footnote.reference.fileType;
+      if (!fileType) {
+        return undefined;
+      }
+      return getAttachmentFileIcons(fileType);
+    }
+    return undefined;
+  };
+
+  private readonly _suffixIcon = (): TemplateResult | undefined => {
+    const referenceType = this.footnote.reference.type;
+    if (referenceType === 'doc') {
+      return DualLinkIcon({ width: '16px', height: '16px' });
+    } else if (referenceType === 'url') {
+      return LinkIcon({ width: '16px', height: '16px' });
+    }
+    return undefined;
+  };
+
+  private readonly _popupLabel = () => {
+    const referenceType = this.footnote.reference.type;
+    let label = '';
+    const { docId, fileName, url } = this.footnote.reference;
+    switch (referenceType) {
+      case 'doc':
+        if (!docId) {
+          return label;
+        }
+        label = this.std.get(DocDisplayMetaProvider).title(docId).value;
+        break;
+      case 'attachment':
+        if (!fileName) {
+          return label;
+        }
+        label = fileName;
+        break;
+      case 'url':
+        if (!url) {
+          return label;
+        }
+        // TODO(@chen): get url title from url, need to implement after LinkPreviewer refactored as an extension
+        label = url;
+        break;
+    }
+    return label;
+  };
+
+  /**
+   * When clicking the chip, we will navigate to the reference doc or open the url
+   */
+  private readonly _onChipClick = () => {
+    const referenceType = this.footnote.reference.type;
+    const { docId, url } = this.footnote.reference;
+    switch (referenceType) {
+      case 'doc':
+        if (!docId) {
+          break;
+        }
+        this.std
+          .getOptional(RefNodeSlotsProvider)
+          ?.docLinkClicked.emit({ pageId: docId });
+        break;
+      case 'url':
+        if (!url) {
+          break;
+        }
+        window.open(url, '_blank');
+        break;
+    }
+    this.abortController.abort();
+  };
+
+  override render() {
+    return html`
+      <div class="footnote-popup-container">
+        <footnote-popup-chip
+          .prefixIcon=${this._prefixIcon()}
+          .label=${this._popupLabel()}
+          .suffixIcon=${this._suffixIcon()}
+          .onClick=${this._onChipClick}
+        ></footnote-popup-chip>
+      </div>
+    `;
+  }
+
+  @property({ attribute: false })
+  accessor footnote!: FootNote;
+
+  @property({ attribute: false })
+  accessor std!: BlockStdScope;
+
+  @property({ attribute: false })
+  accessor abortController!: AbortController;
+}
diff --git a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/index.ts b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/index.ts
index ece36cc15c8b3..fc1e91136ada9 100644
--- a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/index.ts
+++ b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/index.ts
@@ -1,3 +1,5 @@
+export * from './footnote-node/footnote-config.js';
+export { AffineFootnoteNode } from './footnote-node/footnote-node.js';
 export { AffineLink, toggleLinkPopup } from './link-node/index.js';
 export * from './reference-node/reference-config.js';
 export { AffineReference } from './reference-node/reference-node.js';
diff --git a/blocksuite/affine/model/src/consts/doc.ts b/blocksuite/affine/model/src/consts/doc.ts
index 22a5c11d899c5..84b2144217f2f 100644
--- a/blocksuite/affine/model/src/consts/doc.ts
+++ b/blocksuite/affine/model/src/consts/doc.ts
@@ -4,6 +4,10 @@ export type DocMode = 'edgeless' | 'page';
 
 export const DocModes = ['edgeless', 'page'] as const;
 
+export type FootNoteReferenceType = 'doc' | 'attachment' | 'url';
+
+export const FootNoteReferenceTypes = ['doc', 'attachment', 'url'] as const;
+
 /**
  * Custom title and description information.
  *
@@ -42,3 +46,32 @@ export const ReferenceInfoSchema = z
   .merge(AliasInfoSchema);
 
 export type ReferenceInfo = z.infer<typeof ReferenceInfoSchema>;
+
+/**
+ * FootNoteReferenceParamsSchema is used to define the parameters for a footnote reference.
+ * It supports the following types:
+ * 1. docId: string - the id of the doc
+ * 2. blobId: string - the id of the attachment
+ * 3. url: string - the url of the reference
+ * 4. fileName: string - the name of the attachment
+ * 5. fileType: string - the type of the attachment
+ */
+export const FootNoteReferenceParamsSchema = z.object({
+  type: z.enum(FootNoteReferenceTypes),
+  docId: z.string().optional(),
+  blobId: z.string().optional(),
+  fileName: z.string().optional(),
+  fileType: z.string().optional(),
+  url: z.string().optional(),
+});
+
+export type FootNoteReferenceParams = z.infer<
+  typeof FootNoteReferenceParamsSchema
+>;
+
+export const FootNoteSchema = z.object({
+  label: z.string(),
+  reference: FootNoteReferenceParamsSchema,
+});
+
+export type FootNote = z.infer<typeof FootNoteSchema>;
diff --git a/blocksuite/affine/shared/src/types/index.ts b/blocksuite/affine/shared/src/types/index.ts
index aa33d3d815965..3f69765626fcc 100644
--- a/blocksuite/affine/shared/src/types/index.ts
+++ b/blocksuite/affine/shared/src/types/index.ts
@@ -1,4 +1,8 @@
-import type { EmbedCardStyle, ReferenceInfo } from '@blocksuite/affine-model';
+import type {
+  EmbedCardStyle,
+  FootNote,
+  ReferenceInfo,
+} from '@blocksuite/affine-model';
 import type { BlockComponent } from '@blocksuite/block-std';
 import type { BlockModel } from '@blocksuite/store';
 
@@ -70,4 +74,5 @@ export interface AffineTextAttributes {
   background?: string | null;
   color?: string | null;
   latex?: string | null;
+  footnote?: FootNote | null;
 }