svonix

A library for easily integrating Svelte components into Phoenix


License
MIT

Documentation

Svonix

Svonix is a small library that allows you to easily create and use Svelte components in Phoenix.

Svonix is loosely based on the ideas behind Sveltex, but is written to support Phoenix > 1.6, as well as dynamic loading of individual Svelte components to reduce filesizes.

Svonix works with ESBuild which is the default bundler for Phoenix.

Please note that while npm packages can be imported and work as you would expect, Svelte component libraries are currently not supported.

Installation

  1. Add svonix to your list of dependencies in mix.exs:
def deps do
  [
    {:svonix, git: "https://github.com/nikokozak/svonix", tag: "v0.5.1"}
  ]
end
  1. Next, run mix svonix.setup from your Phoenix application's root folder.

Svonix will create an assets/js/svelte folder, and will run npm install after copying over the following files into your assets folder:

  • package.json (listing svelte's dependencies)
  • build.js (custom ESBuild build script)
  1. In your config/dev.exs file, add a watcher (you can replace the ESBuild watcher already there):
config :my_app, MyApp.Endpoint,
    # other options
    watchers: [
        node: ["build.js", "--watch", cd: Path.expand("../assets", __DIR__)]
    ]
  1. Finally, in your assets/js/app.js file, add the following line at the top:
import 'svonix'

Usage

  1. Add new components to the assets/js/svelte folder. For example, we'll add a test.svelte component:
<script>
  export let name;
</script>

<h1>Hey {name}, Phoenix and Svelte setup is working!</h1>
  1. Next, add a Svonix tag where desired (the tag name must match the filename of the component), and pass in the arguments you like:
# lib/myapp_web/templates/page/index.html.heex

<%= Svonix.render "test", %{ name: "Nikolai" } %>

You should see the component rendered in the view.

Advanced Usage

Folder Structure

Svonix supports nesting components to accommodate whatever structure you might desire. In other words, you can structure your svelte files as follows:

assets/js/svelte/
    ARootComponent.svelte
    helpers/
        AHelperComponent.svelte
        AnotherComponent.svelte
            evenMoreHelpers/
                PrettyDeepNesting.svelte

In order to render a component that has been nested (say, for example, AnotherComponent.svelte), simply pass in the path of the component (without an extension) into the render function:

<%= Svonix.render "helpers/AnotherComponent" %>

Private Components

By default, any and all components you declare in your folder structure will generate individual js files in your priv/static/assets/svelte_components folder. This isn't really a problem given that these files are only loaded by the client on demand. Nonetheless, to avoid compiling a given file, simply prepend an _ (underscore) to its name. You can import the file from other components, but it will not be made available to render.

assets/js/svelte/
    ThisWillRender.svelte
    _ThisWillNot.svelte