Inertia.js adapter for Gleam/Wisp

Package Version Hex Docs

Roadmap

This adapter implements Inertia v3 protocol. Currently, it is not implementing all features.

Installation

gleam add wisp_inertia

Usage

mkdir demo && cd demo
gleam new demo --skip-git --skip-github
// server.gleam file

import inertia

pub fn main() -> Nil {
  wisp.configure_logger()
  inertia.init("demo", "v1")
  let secret_key = wisp.random_string(32)

  let assert Ok(_) =
    wisp_mist.handler(router.handle_request, secret_key)
    |> mist.new
    |> mist.bind("0.0.0.0")
    |> mist.port(4000)
    |> mist.start

  io.println("Server up and running")
  process.sleep_forever()
}
// middleware.gleam file

import inertia
import wisp.{type Request, type Response}

pub fn register(req: Request, handle_req: fn(Request) -> Response) -> Response {
  let assert Ok(priv_dir) = wisp.priv_directory(inertia.from_context("demo"))

  use <- wisp.log_request(req)
  use <- wisp.rescue_crashes
  use <- wisp.serve_static(req, under: "/static", from: priv_dir <> "/static")
  use req <- wisp.handle_head(req)
  use req <- inertia.handle_request(req)

  handle_req(req)
}

Make sure that you have created a priv/static folder for static assets.

// router.gleam file

pub fn handle_request(req: Request) -> Response {
  use req <- middleware.register(req)
  let segments = wisp.path_segments(req)

  case segments {
    [] -> handle_index(req)
    _ -> wisp.not_found()
  }
}

fn handle_index(req: wisp.Request) -> wisp.Response {
  inertia.new_page_object(req, "index")
  |> inertia.add_prop("title", json.string("Home Page"))
  |> inertia.render(req)
}

Client

Inside the priv folder, you must to create the following structure for the client.

priv
├── app
│   ├── pages
│   │   └── index.vue
│   └── shared
└── static

The root HTML template file must have this content. The special comments <!-- @inertiaHead --> and <!-- @inertia --> will be replaced by the HTML tags for Inertia.

// priv/index.html

<!doctype html>
<html lang="en">
  <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <!-- @inertiaHead -->
  </head>
  <body>
      <!-- @inertia -->
  </body>
</html>

// priv/app/app.ts file

import { createInertiaApp } from "@inertiajs/vue3";
import "./app.css";

createInertiaApp({
  pages: {
    path: "./pages",
    lazy: true,
  },
});
// priv/pages/index.vue

<script setup lang="ts">
defineProps({
  title: String,
});
</script>

<template>
  <h1>{{ title }}</h1>
</template>

Further documentation can be found at https://hexdocs.pm/wisp_inertia.

Development

gleam run   # Run the project
gleam test  # Run the tests

Examples

TBD

Other Community Adapters

Full list of community adapters is located on inertiajs.com.

License

wisp_inertia is released under the [Apache 2.0] License.

Search Document