Skip to content

This guide covers in-app SDK auth components. For the simplest setup using Bridge’s hosted login page, see the Hosted auth quickstart.

Get up and running with The Bridge Svelte plugin using in-app SDK auth components, with no redirects to external login pages.

npm i @nebulr-group/bridge-svelte

Optional peer dependencies (install only if you need the feature):

| Package | When needed | |---------|-------------| | @stripe/stripe-js | Paid subscription plans (Stripe Checkout) | | @simplewebauthn/browser | Passkey (WebAuthn) authentication |

Initialize Bridge in your root layout load function. The BridgeConfig object tells Bridge your appId and where your login page lives. The routeConfig defines which routes are public and which require authentication.

// src/routes/+layout.ts
import type { LayoutLoad } from './$types';
import type { BridgeConfig, RouteGuardConfig } from '@nebulr-group/bridge-svelte';
import { bridgeBootstrap } from '@nebulr-group/bridge-svelte';

export const ssr = false;

export const load: LayoutLoad = async ({ url }) => {
  const config: BridgeConfig = {
    appId: import.meta.env.VITE_BRIDGE_APP_ID,
    loginRoute: '/auth/login',
  };

  const routeConfig: RouteGuardConfig = {
    rules: [
      { match: '/', public: true },
      { match: new RegExp('^/auth($|/)'), public: true },
    ],
    defaultAccess: 'protected',
  };

  await bridgeBootstrap(url, config, routeConfig);
  return {};
};

Key points:

  • loginRoute: tells Bridge where to redirect unauthenticated users (your in-app login page).
  • defaultAccess: 'protected': all routes require auth unless explicitly marked public.
  • ssr = false: Bridge requires client-side rendering.

Add the BridgeBootstrap component to your root layout. Use the onBootstrapComplete callback to hide content until auth state is resolved.

<!-- src/routes/+layout.svelte -->
<script lang="ts">
  import { BridgeBootstrap } from '@nebulr-group/bridge-svelte';
  import '@nebulr-group/bridge-svelte/styles';

  let { children } = $props();
  let ready = $state(false);

  function onBootstrapComplete() {
    ready = true;
  }
</script>

<BridgeBootstrap {onBootstrapComplete} />

{#if ready}
  {@render children()}
{/if}

Drop the LoginForm component onto a page that matches your loginRoute.

<!-- src/routes/auth/login/+page.svelte -->
<script lang="ts">
  import { LoginForm } from '@nebulr-group/bridge-svelte';
</script>

<div class="login-page">
  <LoginForm showSignupLink />
</div>

<!-- Optional: center the form on the page. Not required for the component to work. -->
<style>
  .login-page {
    display: flex;
    justify-content: center;
    padding: 3rem 1rem;
  }
</style>

That’s it: no callbacks needed. The route guard handles post-login redirect automatically. Auth method visibility (magic link, passkeys, SSO) is derived from your app’s configuration in the Control Center (your admin dashboard at app.thebridge.dev).

LoginForm handles multi-step flows inline: forgot password, magic link requests, passkey login, MFA challenge, MFA setup, and workspace selection (a workspace is called a tenant in the API) all render within the same component automatically when needed.

Optional props: onLogin (fires after successful auth, useful for analytics), onError (fires on auth failure).

<!-- src/routes/auth/signup/+page.svelte -->
<script lang="ts">
  import { SignupForm } from '@nebulr-group/bridge-svelte';
</script>

<div class="signup-page">
  <SignupForm showLoginLink loginHref="/auth/login" />
</div>

<!-- Optional: center the form on the page. -->
<style>
  .signup-page {
    display: flex;
    justify-content: center;
    padding: 3rem 1rem;
  }
</style>

After a successful signup the user receives a verification email. Once verified, they can sign in.

Optional props: onSignup (fires after successful signup), onError (fires on failure).

See Theming & Styles for customization options.

The config object you pass to bridgeBootstrap is a BridgeConfig. The most common fields:

| Field | Default | Description | |-------|---------|-------------| | appId | (required) | Your Bridge app ID | | loginRoute | (unset) | In-app route of your login page; unauthenticated users are redirected here | | signupRoute | (unset) | In-app route of your signup page | | defaultRedirectRoute | '/' | Route to land on after login | | apiBaseUrl | https://api.thebridge.dev | Root URL for the Bridge API (dev override) | | hostedUrl | https://auth.thebridge.dev | Bridge hosted UI URL (dev override) | | debug | false | Enable debug logging |

See the Configuration reference for the full list (token storage, billing routes).

Rather than hardcoding environment-specific values, keep them in a .env file and read them with Vite’s import.meta.env when you build the config (the VITE_ prefix is required for values to reach the browser):

VITE_BRIDGE_APP_ID=your-app-id-here
VITE_BRIDGE_DEFAULT_REDIRECT_ROUTE=/dashboard
const config: BridgeConfig = {
  appId: import.meta.env.VITE_BRIDGE_APP_ID,
  loginRoute: '/auth/login',
  defaultRedirectRoute: import.meta.env.VITE_BRIDGE_DEFAULT_REDIRECT_ROUTE ?? '/',
};