Hyperbole relies heavily on Effectful to run and compose side effects. We can use these Effects in any Page or update.
The Hyperbole effect is automatically available in both, and gives us direct access to the client connection. We can use it to get information about the request, update the page directly, and more. Here is how you might use it to set the page title.
data Titler = Titler
  deriving (Generic, ViewId)

instance HyperView Titler es where
  data Action Titler
    = SetTitle Text
    deriving (Generic, ViewAction)

  update (SetTitle msg) = do
    pageTitle msg
    pure "Check the title"
For more information on the Hyperbole Effect, see Hyperbole Effect
If we want to use an Effect besides Hyperbole, add it as a constraint to any Page and HyperView that needs it
The following HyperView uses a Reader to get a message set at the application level. It also uses Concurrent to delay the response by 500ms:
{-# LANGUAGE UndecidableInstances #-}

page :: (Hyperbole :> es, Concurrent :> es, Reader Text :> es) => Page es '[SlowReader]
page = do
  pure $ hyper SlowReader $ messageView "..."

data SlowReader = SlowReader
  deriving (Generic, ViewId)

instance (Concurrent :> es, Reader Text :> es) => HyperView SlowReader es where
  data Action SlowReader
    = GetMessage
    deriving (Generic, ViewAction)

  update GetMessage = do
    threadDelay 500000
    msg <- ask
    pure $ messageView msg
Then make sure to add the effect when you run your application or page
app :: Application
app = do
  liveApp quickStartDocument $ do
    runConcurrent . runReader @Text "Secret!" $
      runPage page
We can access a database using the IOE effect, but it is better to describe the high-level operations available to the application as a custom effect:
data Todos :: Effect where
  LoadAll :: Todos m [Todo]
  Save :: Todo -> Todos m ()
  Remove :: TodoId -> Todos m ()
  Create :: Text -> Todos m TodoId
To use it we need a run function which converts the abstract operations into a specific implementation. We could implement the Todos Effect using Hyperbole Sessions.
Todos
main :: IO ()
main = do
  run 3000 $ do
    liveApp quickStartDocument (runTodosSession $ runPage simplePage)
Alternatively, we could implement the effect using a database instead.
Todos DB
main :: IO ()
main = do
  db <- initTodosDatabase
  run 3000 $ do
    liveApp quickStartDocument (runTodosSQLite db $ runPage page)
Whichever implementation we use, a HyperView or Page can interact with the data using the same high-level Todos effect by adding it as a constraint:
{-# LANGUAGE UndecidableInstances #-}

simplePage :: (Todos :> es) => Page es '[AllTodos, TodoView]
simplePage = do
  todos <- send Todos.LoadAll
  pure $ do
    hyper AllTodos $ todosView FilterAll todos
▶️ Continue to Managing State