# Use Bootstrap 5 with SvelteKit and Svelte 5

> Add `@winkintel/bootstrap-svelte` to a SvelteKit app with Svelte 5, TypeScript/runes APIs, and Bootstrap 5 CSS while leaving Bootstrap JavaScript out of the bundle.

Source: https://bootstrap-svelte.vercel.app/guides/sveltekit-bootstrap-5 — part of the Bootstrap Svelte documentation (index: https://bootstrap-svelte.vercel.app/llms.txt).

## Install

Install Bootstrap Svelte and Bootstrap together. Svelte `^5.29.0` is a peer dependency supplied by your SvelteKit app.

```bash
pnpm add @winkintel/bootstrap-svelte bootstrap
```

## Add Bootstrap CSS

Bootstrap CSS is required because the components render Bootstrap-compatible classes and markup. Import it once from the root layout or your app stylesheet pipeline.

```html
// src/routes/+layout.ts
import 'bootstrap/dist/css/bootstrap.min.css';

export const prerender = true;
```

If your SvelteKit project already compiles Sass, import Bootstrap SCSS instead.

```html
// src/app.scss
@import 'bootstrap/scss/bootstrap';

// src/routes/+layout.ts
import '../app.scss';
```

## SSR and Hydration

The package components are Svelte components that render during SSR and hydrate in the browser. Do not load Bootstrap's JavaScript bundle or individual Bootstrap plugins for the same controls; Bootstrap Svelte owns the component behavior.

- Keep DOM-only work in Svelte lifecycle code such as `onMount`.
- Use component state, for example `$state(false)`, to control modals, collapses, and offcanvas panels.
- Import Bootstrap CSS once so server-rendered HTML and hydrated HTML use the same class styling.

## Button Example

Use [Button](https://bootstrap-svelte.vercel.app/components/button) for typed Bootstrap button variants, sizes, links, and events.

```html
<script lang="ts">
    import { Button } from '@winkintel/bootstrap-svelte';
</script>

<Button colorVariant="primary" onclick={() => console.log('saved')}>
    Save changes
</Button>
```

## Navbar Example

Use [Navbar](https://bootstrap-svelte.vercel.app/components/navbar) with [Nav](https://bootstrap-svelte.vercel.app/components/nav) and [Container](https://bootstrap-svelte.vercel.app/layout/container).

```html
<script lang="ts">
    import { Container, Nav, Navbar } from '@winkintel/bootstrap-svelte';
</script>

<Navbar.Root expandOnBreakpoint="lg" class="bg-body-tertiary">
    <Container isFluid={true}>
        <Navbar.Brand href="/">Acme</Navbar.Brand>
        <Navbar.Toggler ariaLabel="Toggle navigation">
            <Navbar.TogglerIcon />
        </Navbar.Toggler>
        <Navbar.Collapse id="mainNavbar">
            <Navbar.Nav class="me-auto mb-2 mb-lg-0">
                <Nav.Item><Nav.Link isActive={true} href="/">Home</Nav.Link></Nav.Item>
                <Nav.Item><Nav.Link href="/settings">Settings</Nav.Link></Nav.Item>
            </Navbar.Nav>
        </Navbar.Collapse>
    </Container>
</Navbar.Root>
```

## Form Example

Use [form controls](https://bootstrap-svelte.vercel.app/form/form-controls) with Svelte bindings and Bootstrap validation classes.

```html
<script lang="ts">
    import { Button, Form } from '@winkintel/bootstrap-svelte';

    let email = $state('');
    let accepted = $state(false);
</script>

<Form.Root method="post" class="needs-validation">
    <div class="mb-3">
        <Form.InputLabel for="email">Email address</Form.InputLabel>
        <Form.EmailInput id="email" name="email" bind:value={email} aria-describedby="email-help" required />
        <Form.HelperText id="email-help">Use a work email address.</Form.HelperText>
    </div>
    <Form.Check class="mb-3">
        <Form.CheckInput id="terms" name="terms" bind:checked={accepted} required />
        <Form.CheckLabel for="terms">I accept the terms</Form.CheckLabel>
    </Form.Check>
    <Button type="submit" colorVariant="primary">Create account</Button>
</Form.Root>
```

## Modal Example

Use [Modal](https://bootstrap-svelte.vercel.app/components/modal) state instead of Bootstrap JavaScript data attributes.

```html
<script lang="ts">
    import { Button, Modal } from '@winkintel/bootstrap-svelte';

    let isModalShown = $state(false);
</script>

<Button colorVariant="primary" onclick={() => (isModalShown = true)}>
    Open modal
</Button>

<Modal.Root isShown={isModalShown} onHidden={() => (isModalShown = false)}>
    <Modal.Dialog>
        <Modal.Content>
            <Modal.Header isDismissible={true}>
                <Modal.Title level={2} class="fs-5">Confirm action</Modal.Title>
            </Modal.Header>
            <Modal.Body>
                <p>Review the details before continuing.</p>
            </Modal.Body>
            <Modal.Footer>
                <Button colorVariant="secondary" onclick={() => (isModalShown = false)}>Cancel</Button>
                <Button colorVariant="primary">Continue</Button>
            </Modal.Footer>
        </Modal.Content>
    </Modal.Dialog>
</Modal.Root>
```
