Embedding SVGs into Lustre apps
A demo of how to use embeds/files
and html_lustre_converter together.
It contains a very simple lustre demo app, showing our favorite Starfish!
The build script is located in test/build.gleam
, as suggested on the Discord.
The icons/lucy.svg
was taken from the Gleam website, with the width
and height
attributes removed for demo purposes.
You can check out the full example project here.
Running
Since html_lustre_converter
depends on javascript_dom_parser,
only the Deno runtime is supported right now.
gleam run -m build
gleam run -m lustre/dev start
build.gleam
source code
NOTE: In a real project, you would add a seperate build
path dev dependency.
This avoids issues when regenerating files that your project already depends on.
import embeds/files
import embeds/generate
import gleam/io
import gleam/option
import gleam/string
import html_lustre_converter
import javascript_dom_parser/deno_polyfill
pub fn main() {
// required by html_lustre_converter
deno_polyfill.install_polyfill()
let result =
files.generate(files.Options(
// where to get files from?
sources: [
files.Source(
// take all files from ./icons (relative to the project root)...
src: "./icons",
// generate a module called "icons.gleam"...
module: "icons",
// put all found icons in the same module...
flatten: files.FlattenAll,
// regardless of how deep the directory tree is...
max_depth: option.None,
// and we are only interested in *.svg files...
filter: fn(_is_dir, path) {
// we are only interested in svg files.
string.ends_with(path, ".svg")
},
),
],
// how to convert a file into Gleam source code?
print: fn(path, data) {
// if we get a svg text file, convert it using html_lustre_converter.
// NOTE: we technically already filtered in sources,
// so this check is reduntant currently!
case string.ends_with(path, ".svg"), data {
True, generate.Text(svg) ->
generate.FunctionBody(html_lustre_converter.convert(svg))
_, _ -> generate.Skip
}
},
// add the required imports
header: string.join(
[
"import lustre/element/svg",
// html_lustre_converter generates attribute calls without namespaces
"import lustre/attribute.{attribute}",
],
"\n",
),
// only regenerate the module if our icons have changed.
force: False,
))
case result {
Ok(Nil) -> Nil
Error(errs) -> io.println_error(generate.describe_errors(errs))
}
}