nuxt-symbolics

A Nuxt module for displaying confessions, catechisms, and creeds
2,786
Install
npm install nuxt-symbolics
Latest Version:2.6.0
Vue:3
License:CC0-1.0
Last Updated:Aug 5, 2026
Links: GitLab  ·  npm
Maintainer: cco3

Nuxt Symbolics

Vue components for websites displaying symbolics—creeds, confessions, and catechisms of the Christian faith.

Importing

npm install --save nuxt-symbolics

nuxt.config.ts:

export default defineNuxtConfig({
  modules: ["nuxt-symbolics"],
  symbolics: {
    // A prefix to attach to component names.
    // default: "Symbolics"
    componentPrefix: "Sym",
    // A prefix to attach to custom css classes like `hyperlink`.
    // default: ""
    cssPrefix: "symbolics-",
    siteName: "The Baptist Confession",
    siteEmail: "info@example.com",
  },
});

Data

SymbolicsParts

content/confession/chapters/01.yaml

id: "1"
title: Of The Holy Scriptures
num_paragraphs: 10

ConfessionUnits

id: "1.1"
next: "1.2"
parent: "1"
segments:
  - text: >-
      The Holy Scripture is the only sufficient, certain, and infallible rule
      of all saving knowledge, faith, and obedience.
    proofs: 2 Timothy 3:15–17; Isaiah 8:20; Luke 16:29, 31; Ephesians 2:20
  - text: >-
      Although the light of nature, and the works of creation and providence do
      so far manifest the goodness, wisdom, and power of God, as to leave men
      inexcusable; yet they are not sufficient to give that knowledge of God
      and His will which is necessary unto salvation.
    proofs: Romans 1:19–21; 2:14–15; Psalm 19:1–3
  - text: >-
      Therefore it pleased the Lord at sundry times and in divers manners
      to reveal Himself, and to declare that His will unto His church;
    proofs: Hebrews 1:1
  - text: >-
      and afterward for the better preserving and propagating of the truth, and
      for the more sure establishment and comfort of the church against the
      corruption of the flesh, and the malice of Satan, and of the world, to
      commit the same wholly unto writing; which maketh the Holy Scriptures to
      be most necessary, those former ways of God's revealing His will unto His
      people being now ceased.
    proofs: Proverbs 22:19–21; Romans 15:4; 2 Peter 1:19–20

CatechismUnits

id: "1"
question: Who is the first and chiefest being?
segments:
  - text: God is the first and chiefest being.
    proofs: Isaiah 44:6; 48:12; Psalm 97:9

Components

SymbolicsLayout

Consider using this in app.vue.

<template>
  <SymbolicsApp>
    <MyMessageHandler />
  </SymbolicsApp>
</template>

SymbolicsList

<template>
  <SymbolicsList
    :parts="chapters"
    :units="paragraphs"
    :level="2"
    :to="(id: string) => `/navigation/${id}`"
    table-of-contents
  />
</template>

<script setup lang="ts">
import type { SymbolicsList, SymbolicsUnit } from "#symbolics";

const chapters = await queryCollection("lbcf1689Chapters")
  .where("symbolics_id", "=", "1")
  .first();
const paragraphs = await queryCollection("lbcf1689Paragraphs")
  .where("symbolics_id", "=", "1.1")
  .first();
</script>

SymbolicsView

<template>
  <SymbolicsView unit="unit" docname="The Baptist Catechism" id-prefix="bc-" />
</template>

<script setup lang="ts">
const unit = await useSymbolicsUnit("bc1695", "1");
</script>

We recommend wrapping this in a https://vuejs.org/guide/built-ins/suspense tag.

SymbolicsLayout

Consider using this in layouts/default.vue.

<template>
  <SymbolicsLayout>
    <slot />
    <template #footer-left>baptistconfession.org</template>
    <template #footer-right>
      <NuxtLink to="/copyright" class="hyperlink">Copyright</NuxtLink>
    </template>
  </SymbolicsLayout>
</template>

SymbolicsPage

<SymbolicsPage size="lg" :title="My Page" subtitle="It's the Best Page">
  <template #introduction>
    <ContentDoc path="prose/lorem" />
  </template>
  <ContentDoc path="prose/ipsum" class="prose" />
</SymbolicsPage>

SymbolicsProseAccordion

<template>
  <SymbolicsProseAccordion :value="prose" :limit="1" />
</template>

Each section is headed by its title and anchored by its prose anchor, so it can be linked to with e.g. #nicene-creed. Following such a link opens the section. Collapsed sections stay in the document so search engines still see their text.

limit renders only the first n sections, and id-prefix prefixes every anchor.

SymbolicsTableOfContents

<template>
  <SymbolicsTableOfContents
    :prose="[preface]"
    :units="questions"
    part-class="w-60"
    unit-class="w-10"
    @select="close"
  />
</template>

units are listed by id, parts and prose by title. Each links to the matching anchor on the page: #{id} for a part or unit, and the prose anchor for a prose document. prose is listed first; for a document that belongs after the units (an appendix), use a second table of contents.

select is emitted whenever an entry is followed, e.g. to close the SymbolicsPage slide-over.

SymbolicsDomain

This will display the configured siteDomain as a link.

<template>
  <p><SymbolicsDomain /> is a project of the Cool Collective.</p>
</template>

SymbolicsEmail

This will display the configured siteEmail as a link.

<template>
  <p>Email us! <SymbolicsEmail /></p>
</template>

SymbolicsError

Consider using SymbolicsError in error.vue.

<template>
  <SymbolicsError :error="error" catechism>
    <p>Feel free to contact the webmaster about this error.</p>
  </SymbolicsError>
</template>

<script setup lang="ts">
defineProps<{
  error: { statusCode: number; stack?: string; message?: string };
}>();
</script>

SymbolicsEsvCopyright

Since the SymbolicsLayout includes settings to turn on ESV proof text expansion, this component provides a simple way to include the ESV copyright statement. It is added to Nuxt globally, so it can be used from @nuxt/content.

copyright.md

Copyright Information

---

:EsvCopyrightStatement

SymbolicsCreativeCommonsZero

copyright.md

Copyright Information

:SymbolicsCreativeCommonsZero{author="Mr. Author"}

Types

import type {
  CatechismUnit,
  ConfessionUnit,
  SymbolicsPart,
  SymbolicsUnit,
} from "#symbolics";

Composables

useSymbolicsUnit

const unit = await useSymbolicsUnit("confession", "paragraphs", "01_01");

This works much like queryCollection from @nuxt/content, but:

  • performs a type assertion to SymbolicsUnit, and
  • throws a fatal 404 if none is found.

The fatal 404 is necessary for proper 404 behavior when using SSG.

Utilities

isCatechismUnit

import { isCatechismUnit } from "#symbolics";

if (isCatechism(unit)) {
  // eslint-disable-next-line no-console
  console.log(unit.question);
}

firstString

import { firstString } from "#symbolics";

const route = useRoute();
const id = firstString(route.params.id);

padParts

import { padParts } from "#symbolics";

const fileName = `${padParts("1.1", 2)}.yml`; // "01_01.yml"

proseAnchor

import { proseAnchor } from "#symbolics";

const doc = await useSymbolicsUnit(
  "aoc1680Prose",
  "symbolics/catechisms/aoc1680/prose/01-nicene_creed",
);
proseAnchor(doc); // "nicene-creed"

The anchor is the last segment of the document's stem, without any ordering prefix and with underscores as hyphens, so renumbering a file does not change its anchor. SymbolicsProseAccordion and SymbolicsTableOfContents both use it, and it is exported for anything else that links to a prose section.

Other Imports

All other imports can be retrieved from the specific import path under #symbolics.

import LoadingSpinner from "#symbolics/components/LoadingSpinner.vue";
import useStaticPassage from "#symbolics/composables/use-symbolics-unit";
import { makeLink } from "#symbolics/utils/base";

CSS classes

<NuxtLink to="/path" class="hyperlink" />

prose

<p class="prose" />
  This is justified text.
</p>

Version History

Version Released Vue License
2.6.0 ^3.0 CC0-1.0
2.5.12 ^3.0 CC0-1.0
2.5.11 ^3.0 CC0-1.0
2.5.10 ^3.0 CC0-1.0
2.5.9 ^3.0 CC0-1.0