The session provides a way to store small amounts of information that persists between requests in your IHP application.
Sessions use cryptographically signed and encrypted cookies. The encryption key is automatically generated and stored in Config/client_session_key.aes.
Store only scalar values (strings, numbers, UUIDs) in the session, not complex data structures. For example, store the user ID instead of the entire user record.
Writing to the Session
Use setSession in your controller actions:
Supports multiple data types:
action SessionExampleAction = do
setSession "meaningOfLife" (42 :: Int)
setSession "isActive" True
setSession "userId" someUUID
Reading from the Session
Use getSession to retrieve values:
action SessionExampleAction = do
userEmail :: Maybe Text <- getSession "userEmail"
Returns Just value if set, Nothing otherwise.
With different types:
action SessionExampleAction = do
counter :: Maybe Int <- getSession "counter"
userId :: Maybe UUID <- getSession "userId"
isActive :: Maybe Bool <- getSession "isActive"
Deleting from the Session
Use deleteSession to remove values:
action LogoutAction = do
deleteSession "userId"
redirectTo HomeAction
Flash Messages
Flash messages display success or error messages on the next request, then automatically disappear.
Setting Flash Messages
Success messages:
action CreatePostAction = do
-- ... create post ...
setSuccessMessage "Your Post has been created successfully"
redirectTo ShowPostAction { .. }
Error messages:
action CreatePostAction = do
unless isAllowedToPost do
setErrorMessage "You don't have the required permissions"
redirectTo NewPostAction
-- ...
Flash messages are stored in the session and automatically cleared after the next request (except for redirects and JSON responses).
Rendering Flash Messages
Add renderFlashMessages to your layout:
defaultLayout :: Html -> Html
defaultLayout inner = [hsx|
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<div class="container mt-2">
{renderFlashMessages}
{inner}
</div>
</body>
</html>
|]
Generated HTML:
<div class="alert alert-success">Your Post has been created successfully</div>
<div class="alert alert-danger">You don't have the required permissions</div>
Custom Flash Message Rendering
Access flash messages directly in views:
let flashMessages :: [FlashMessage] = fromFrozenContext
-- Custom rendering
[hsx|
{forEach flashMessages renderCustomFlash}
|]
renderCustomFlash :: FlashMessage -> Html
renderCustomFlash (SuccessFlashMessage message) = [hsx|
<div class="custom-success">{message}</div>
|]
renderCustomFlash (ErrorFlashMessage message) = [hsx|
<div class="custom-error">{message}</div>
|]
Session Cookie Configuration
Default settings:
- Max age: 30 days
- SameSite policy: Lax (CSRF protection)
- Encryption: AES (via clientsession library)
Best Practices
- Keep it small - Sessions are stored in cookies (limited size)
- Store IDs, not objects - Reference database records by ID
- Use flash messages - For one-time user feedback
- Clear sensitive data - Remove session data when no longer needed
Common Patterns
action AddToCartAction { productId } = do
cartCount :: Maybe Int <- getSession "cartCount"
let newCount = fromMaybe 0 cartCount + 1
setSession "cartCount" newCount
redirectTo ProductsAction
Remember Last Visited Page
action ShowProductAction { productId } = do
setSession "lastVisited" ("/products/" <> show productId)
-- ...
User Preferences
action SetThemeAction = do
theme :: Text <- param "theme"
setSession "preferredTheme" theme
redirectBack