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
app :: Application
app = do
  liveApp quickStartDocument $ do
    runConcurrent . runReader @Text "Secret!" $
      runPage page
We could run 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

loadAll :: (Todos :> es) => Eff es [Todo]
loadAll = send LoadAll
Just like built-in effects, we add it to any HyperView and Page that needs it as a constraint.
{-# LANGUAGE UndecidableInstances #-}

simplePage :: (Todos :> es) => Page es '[AllTodos, TodoView]
simplePage = do
  todos <- Todos.loadAll
  pure $ do
    hyper AllTodos $ todosView FilterAll todos
We run a custom effect in our Application just like any other. The TodoMVC example implements the Todos Effect using Hyperbole sessions, but you could write a different runner that connects to a database instead.
main :: IO ()
main = do
  run 3000 $ do
    liveApp quickStartDocument (runTodosSession $ runPage simplePage)
Implementing a database runner as a custom Effect is beyond the scope of this documentation, but see the following: