Skip to Content

Svelte

This packages provides Hellō button components that you can use in a Svelte SPA.

Setup

To add Hellō to your Svelte application, in your project directory:

Install the package

npm i @hellocoop/svelte

Add Hellō stylesheet

To provide the button styling, add the below code to the <head> section of the index.html:

<link rel="stylesheet" href="https://cdn.hello.coop/css/hello-btn.css"/>

Components

import { ContinueButton, LoginButton, UpdateProfileButton, LoggedIn, LoggedOut, HelloProvider, useAuth, logOut, getLogOutRoute } from '@hellocoop/svelte'

Buttons

<ContinueButton/> - provides [ ō Continue with Hellō ]

<LoginButton/> - provides [ ō Login with Hellō ]

<UpdateProfileButton/> - provides [ ō Update Profile with Hellō ]

Optional properties:

  • scope - Array of Hellō scope values. Default ['openid', 'email', 'name', 'picture'].
  • targetURI - defaults to HELLO_DEFAULT_TARGET_ROUTE or ’/’
  • providerHint - Array of provider hints. Example ['github', 'gitlab', 'email--', 'apple--', 'microsoft--'] would always recommend GitHub, GitLab, and Google.
  • loginHint - A hint for which user account to use. Example name@domain.example.
  • domainHint - A hint for the domain of the user’s managed account. Example domain.example.
  • promptLogin - defaults to false. Will require the user to re-authenticate at their login provider.
  • promptConsent - defaults to false. Will require the user to review, and potentially change, released claims.

Optional button styling properties:

  • color - white | black
  • theme - ignore-light | ignore-dark | aware-invert | aware-static
  • hover - pop | glow | flare | none

Explore styling with the button playground

Login Status Components

<LoggedIn> - renders children only when user is logged in

<LoggedOut> - renders children only when user is logged out

<LoggedIn> <div>Welcome back!</div> </LoggedIn> <LoggedOut> <ContinueButton /> </LoggedOut>

useAuth() Hook

Hook to get authentication state and user information.

const { auth, isLoading, isLoggedIn } = useAuth() // auth contains: // - isLoggedIn: boolean // - sub: string (user identifier) // - name: string // - email: string // - picture: string // - iat: number (issued at timestamp)

Logout Functions

logOut() - redirects to logout route

getLogOutRoute() - returns logout route URL

<script> import { logOut, getLogOutRoute } from '@hellocoop/svelte' // Redirect to logout function handleLogout() { logOut() } // Get logout URL for Link component const logoutUrl = getLogOutRoute() </script> <button on:click={handleLogout}>Logout</button>

<HelloProvider/>

By default, clicking the Hellō button would redirect to /api/hellocoop?login=true endpoint with the optional properties as additional query parameters. To override this behavior, wrap your app with the <HelloProvider/> component and pass the config object as a prop to the provider.

Props:

  • auth - Auth object (optional, for server-side rendered auth)
  • config - Route configuration (optional)
App.svelte
<script> import { HelloProvider } from '@hellocoop/svelte'; // Default configuration const config = { login: '/api/hellocoop?login=true', auth: '/api/hellocoop?auth=true', logout: '/api/hellocoop?logout=true' } // Optional: pass auth object for server-side rendered auth export let auth = {} </script> <HelloProvider {auth} {config}> <main> <LoggedIn> <div>Welcome {auth?.name}!</div> </LoggedIn> <LoggedOut> <ContinueButton /> </LoggedOut> </main> </HelloProvider>

Complete Example

Here’s a complete example showing how to use all the components together:

App.svelte
<script> import { HelloProvider, LoggedIn, LoggedOut, ContinueButton, LoginButton, UpdateProfileButton, useAuth, logOut, getLogOutRoute } from '@hellocoop/svelte' // Optional: pass auth object for server-side rendered auth export let auth = {} </script> <HelloProvider {auth}> <UserProfile /> </HelloProvider> <!-- UserProfile.svelte --> <script> import { useAuth, logOut } from '@hellocoop/svelte' const { auth, isLoading, isLoggedIn } = useAuth() function handleLogout() { logOut() } </script> {#if isLoading} <div>Loading...</div> {:else if isLoggedIn} <div> <img src={auth.picture} alt={auth.name} /> <h2>Welcome {auth.name}!</h2> <p>{auth.email}</p> <button on:click={handleLogout}>Logout</button> <UpdateProfileButton targetURI="/profile" /> </div> {:else} <div> <ContinueButton targetURI="/dashboard" /> <LoginButton targetURI="/dashboard" /> </div> {/if}