Create your own UI
The login and signup flows are pretty standard: they allow the user to sign up and then log in with their username and password. The signup flow validates the username and password and then creates a new user entity in the database.
Read more about the default username and password validation rules in the auth overview docs.
Even though Wasp offers premade Auth UI for your authentication flows, there are times where you might want more customization, so we also give you the option to create your own UI and call Wasp's auth actions on your own code, similar to how Auth UI does it under the hood.
Example code
Below you can find a starting point for making your own UI in the client code. You can customize any of its look and behaviour, just make sure to call the signup() or login() functions imported from wasp/client/auth.
Sign-up
- JavaScript
- TypeScript
import { login, signup } from 'wasp/client/auth'
import { useState } from 'react'
import { useNavigate } from 'react-router'
export function SignupPage() {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState(null)
const navigate = useNavigate()
async function handleSubmit(event) {
event.preventDefault()
setError(null)
try {
await signup({ username, password })
await login({ username, password })
navigate('/')
} catch (error) {
setError(error)
}
}
return (
<form onSubmit={handleSubmit}>
{error && <p>Error: {error.message}</p>}
<input
type="text"
autoComplete="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit">Sign Up</button>
</form>
)
}
import { login, signup } from 'wasp/client/auth'
import { useState } from 'react'
import { useNavigate } from 'react-router'
export function SignupPage() {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState<Error | null>(null)
const navigate = useNavigate()
async function handleSubmit(event: React.SubmitEvent<HTMLFormElement>) {
event.preventDefault()
setError(null)
try {
await signup({ username, password })
await login({ username, password })
navigate('/')
} catch (error: unknown) {
setError(error as Error)
}
}
return (
<form onSubmit={handleSubmit}>
{error && <p>Error: {error.message}</p>}
<input
type="text"
autoComplete="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit">Sign Up</button>
</form>
)
}
Login
- JavaScript
- TypeScript
import { login } from 'wasp/client/auth'
import { useState } from 'react'
import { useNavigate } from 'react-router'
export function LoginPage() {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState(null)
const navigate = useNavigate()
async function handleSubmit(event) {
event.preventDefault()
setError(null)
try {
await login({ username, password })
navigate('/')
} catch (error) {
setError(error)
}
}
return (
<form onSubmit={handleSubmit}>
{error && <p>Error: {error.message}</p>}
<input
type="text"
autoComplete="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit">Log In</button>
</form>
)
}
import { login } from 'wasp/client/auth'
import { useState } from 'react'
import { useNavigate } from 'react-router'
export function LoginPage() {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState<Error | null>(null)
const navigate = useNavigate()
async function handleSubmit(event: React.SubmitEvent<HTMLFormElement>) {
event.preventDefault()
setError(null)
try {
await login({ username, password })
navigate('/')
} catch (error: unknown) {
setError(error as Error)
}
}
return (
<form onSubmit={handleSubmit}>
{error && <p>Error: {error.message}</p>}
<input
type="text"
autoComplete="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit">Log In</button>
</form>
)
}
API Reference
You can import the following functions from wasp/client/auth:
login()
login »
Log the user in with their username and password.
signup()
signup »
Sign the user up with a username and password.