Skip to main content
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:
action SessionExampleAction = do
    setSession "userEmail" "[email protected]"
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>
|]
Default settings:
  • Max age: 30 days
  • SameSite policy: Lax (CSRF protection)
  • Encryption: AES (via clientsession library)
For technical details, see the clientsession library documentation.

Best Practices

  1. Keep it small - Sessions are stored in cookies (limited size)
  2. Store IDs, not objects - Reference database records by ID
  3. Use flash messages - For one-time user feedback
  4. Clear sensitive data - Remove session data when no longer needed

Common Patterns

Shopping Cart Counter

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

Build docs developers (and LLMs) love