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 toHELLO_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. Examplename@domain.example
.domainHint
- A hint for the domain of the user's managed account. Exampledomain.example
.promptLogin
- defaults tofalse
. Will require the user to re-authenticate at their login provider.promptConsent
- defaults tofalse
. Will require the user to review, and potentially change, released claims.
Optional button styling properties:
color
- white | blacktheme
- ignore-light | ignore-dark | aware-invert | aware-statichover
- 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)
<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:
<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}