Quick start
Put a working Soul surface in a page, then choose how the files reach it.
The markup is the same with a bundler or with the drop-in. soul.css
carries the tokens and the class layer, and the JavaScript registers the
sds-* elements.
How the files arrive#
Install the frontend mirror and Lit in a project with a bundler:
npm install @typo3/soul-frontend litnpm install @typo3/soul-frontend lit
Import the package entry and the stylesheet from the application's JavaScript entry:
import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';
The package entry leaves Lit external, so the application and the elements share one reactive-element registry.
Install the frontend mirror and Lit in a project with a bundler:
npm install @typo3/soul-frontend litnpm install @typo3/soul-frontend lit
Import the package entry and the stylesheet from the application's JavaScript entry:
import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';
The package entry leaves Lit external, so the application and the elements share one reactive-element registry.
Copy dist/ from the frontend mirror to a public soul/
directory, whole. The stylesheet resolves the fonts beside itself. The
script resolves assets/icons/sprites/ inside it, one file per icon
category. A build that moves the module away from those assets says
where they went with setIconSprites(), which takes the directory.
A page that must not fetch carries the glyphs in the script:
inlineIcons().
<script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script><script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script>
soul-boot.js belongs before the stylesheet where the page has a
mode switch. Leave it out when the page follows the reader's system
setting and offers no switch.
Copy dist/ from the frontend mirror to a public soul/
directory, whole. The stylesheet resolves the fonts beside itself. The
script resolves assets/icons/sprites/ inside it, one file per icon
category. A build that moves the module away from those assets says
where they went with setIconSprites(), which takes the directory.
A page that must not fetch carries the glyphs in the script:
inlineIcons().
<script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script><script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script>
soul-boot.js belongs before the stylesheet where the page has a
mode switch. Leave it out when the page follows the reader's system
setting and offers no switch.
Install the frontend mirror and Lit in a project with a bundler:
npm install @typo3/soul-frontend litnpm install @typo3/soul-frontend lit
Import the package entry and the stylesheet from the application's JavaScript entry:
import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';
The package entry leaves Lit external, so the application and the elements share one reactive-element registry.
Install the frontend mirror and Lit in a project with a bundler:
npm install @typo3/soul-frontend litnpm install @typo3/soul-frontend lit
Import the package entry and the stylesheet from the application's JavaScript entry:
import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';import '@typo3/soul-frontend';
import '@typo3/soul-frontend/dist/soul.css';
The package entry leaves Lit external, so the application and the elements share one reactive-element registry.
Copy dist/ from the frontend mirror to a public soul/
directory, whole. The stylesheet resolves the fonts beside itself. The
script resolves assets/icons/sprites/ inside it, one file per icon
category. A build that moves the module away from those assets says
where they went with setIconSprites(), which takes the directory.
A page that must not fetch carries the glyphs in the script:
inlineIcons().
<script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script><script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script>
soul-boot.js belongs before the stylesheet where the page has a
mode switch. Leave it out when the page follows the reader's system
setting and offers no switch.
Copy dist/ from the frontend mirror to a public soul/
directory, whole. The stylesheet resolves the fonts beside itself. The
script resolves assets/icons/sprites/ inside it, one file per icon
category. A build that moves the module away from those assets says
where they went with setIconSprites(), which takes the directory.
A page that must not fetch carries the glyphs in the script:
inlineIcons().
<script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script><script src="/soul/soul-boot.js"></script>
<link rel="stylesheet" href="/soul/soul.css">
<script type="module" src="/soul/soul.js"></script>
soul-boot.js belongs before the stylesheet where the page has a
mode switch. Leave it out when the page follows the reader's system
setting and offers no switch.
Write the surface#
dist/custom-elements.json in the package says what each element
takes, compiled from the components themselves. Every tag with its
attributes, their types, the events it sends, the classes it draws and if
it takes content. Point an editor or a generator at that file.
Components is the same contract for a reader.
npx soul-check src/ holds the other half in the project's own tree. A
class an element draws, written by hand, is a component rebuilt, and the
check names it with the element to write instead. Put it beside the
tests. A rule that exists only as prose is one every fresh session finds
again.
dist/custom-elements.json in the package says what each element
takes, compiled from the components themselves. Every tag with its
attributes, their types, the events it sends, the classes it draws and if
it takes content. Point an editor or a generator at that file.
Components is the same contract for a reader.
npx soul-check src/ holds the other half in the project's own tree. A
class an element draws, written by hand, is a component rebuilt, and the
check names it with the element to write instead. Put it beside the
tests. A rule that exists only as prose is one every fresh session finds
again.
Put sds-app on the application root, then address the elements the
surface needs. A complete page adds the shell, the skip link and one of the
bodies in Page layout around this content:
<div class="sds-app">
<section class="sds-page" aria-labelledby="package-status">
<h1 id="package-status">Package status</h1>
<sds-note tone="info" heading="Rendered from Soul">
<p>The component styles and behaviour come from the same package.</p>
</sds-note>
<sds-button href="/docs/">Read the documentation</sds-button>
</section>
</div><div class="sds-app">
<section class="sds-page" aria-labelledby="package-status">
<h1 id="package-status">Package status</h1>
<sds-note tone="info" heading="Rendered from Soul">
<p>The component styles and behaviour come from the same package.</p>
</sds-note>
<sds-button href="/docs/">Read the documentation</sds-button>
</section>
</div>
The result is a surface on the canvas, an information note with its labelled
glyph, and a primary press as a real link. The custom elements render light
DOM and emit the same sds- classes a server writes.
Classes where no script runs#
A server that already knows the answer can write the class layer directly.
It needs soul.css and no JavaScript:
<a class="sds-btn sds-btn--primary" href="/docs/">
Read the documentation
</a><a class="sds-btn sds-btn--primary" href="/docs/">
Read the documentation
</a>
Prefer the element where there is behaviour, state or structure it owns. Prefer the class where the server has produced final markup and nothing in the page changes it.
Where to continue#
| Need | Read |
|---|---|
| the page shell, bands and responsive frame | Page layout |
| an element's attributes, properties and events | Components |
| headings, lists, tables and prose from a renderer | Documents |
| the visual rules behind the tokens and components | Design system |