useLoginBy()
useLoginBy() returns a login trigger function that the caller invokes on demand (typically
bound to <button @click>). When invoked it auto-routes to either dialog login
(useLoginDialog) or page-redirect login (navigateTo('/login')), or you can force one of
the two.
Note: this composable is not a setter (there is no
loginBy: Ref/setLoginBy()); each call touseLoginBy()returns a fresh trigger function ready to execute. The name "useLoginBy" means "log in by which method" — not "switch the login method".
Basic Usage (recommended: Auto)
<script setup lang="ts">
const triggerLogin = useLoginBy() // default 'Auto'
</script>
<template>
<button @click="triggerLogin()">Sign in</button>
</template>
Auto routes based on UA:
- Desktop → dialog (better desktop interaction)
- Android / iOS WebView → redirect (WebView dialog UX is poor)
- 6 mainstream browsers (Chrome / Safari / Edge / Firefox / Opera / Samsung Internet) → dialog
- China-region browsers / WeChat WebView / QQ / UC / MIUI / Vivo / Oppo / Quark / 360 / Sogou → redirect (these environments often hijack videos / block dialogs)
- Other mobile browsers → redirect (conservative fallback)
Force Dialog (e.g., desktop sidebar sign-in button)
const loginDialog = useLoginBy('Dialog')
loginDialog() // immediately shows the login dialog
Suitable when the environment is known to be desktop — no need for auto-detection.
Force Redirect (e.g., inside WeChat / Public Account WebView)
const goLogin = useLoginBy('Redirect')
goLogin() // immediately navigateTo('/login?redirect=<current-path>')
The redirect target /login is a fixed framework convention (not configurable; the starter template ships app/pages/login.vue, and auth.guestPaths includes /login by default). The redirect URL carries a redirect query parameter so the login page can use
useRoute().query.redirect to bounce back after successful login:
// /login page
const router = useRouter()
const redirect = useRoute().query.redirect as string | undefined
async function onLoginSuccess() {
await navigateTo(redirect || '/')
}
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
type | 'Dialog' | 'Redirect' | 'Auto' | 'Auto' | Login mode. Auto decides by UA; the other two force the mode |
Return Value
| Type | Description |
|---|---|
() => void | Promise<void> | A trigger function ready to invoke. Dialog mode returns void; Redirect mode returns Promise<void> (navigateTo is async) |
Notes
- Not a reactive state: the return value is a function, not a
Ref. Every call touseLoginBy()returns a fresh trigger. If your business needs to "switch" the login mode (user preference), manage that state yourself viauseState/localStorageand pass the state touseLoginBy(state.value)on each call. - Redirect query is auto-written:
Redirectmode callsnavigateTo({ path: '/login', query: { redirect: useRoute().fullPath } })— no need to build the query manually. - WebView detection fallback: custom WebViews with UAs like
Version/4.0 Chrome/X.Y(without the; wvmarker) are still correctly identified as WebView → redirect. - Pairs with
useLoginDialog:Dialogmode reads the globalvisiblestate fromuseLoginDialog(). Mount<SwLoginDialog>(or a custom dialog component subscribed tovisible) in your root layout for this mode to work.