View Source LiveSvelte (LiveSvelte v0.1.0-rc5)
features
Features
- Server-Side Rendered (SSR) Svelte
- End-To-End Reactivity
- Svelte Preprocessing support with svelte-preprocess
- Tailwind support
demo
Demo
You can find the code for this in /examples/breaking_news
.
News items are synced with the server while the speed is only client side (but could be server side if desired).
https://user-images.githubusercontent.com/3637265/221381302-c9ff31fb-77a0-44f2-8c79-1a1a6b7e5893.mp4
why-livesvelte
Why LiveSvelte
Phoenix LiveView enables rich, real-time user experiences with server-rendered HTML. It works by communicating any state changes through a websocket and updating the DOM in realtime. You can get a really good user experience without ever needing to write any client side code.
LiveSvelte builds on top of Phoenix LiveView to allow for easy client side state management while still allowing for communication over the websocket.
docs
Docs
installation
Installation
- Add
live_svelte
to your list of dependencies inmix.exs
:
defp deps do
[
{:live_svelte, "~> 0.1.0-rc5"}
]
end
- Adjust the
setup
andassets.deploy
aliases inmix.exs
:
defp aliases do
[
setup: ["deps.get", "ecto.setup", "cmd --cd assets npm install"],
...,
"assets.deploy": ["cmd --cd assets node build.js --deploy", "phx.digest"]
]
end
Run the following in your terminal
mix deps.get mix live_svelte.setup
Make sure you have
node
installed, you can verify this by runningnode --version
in your project directory.Finally, remove the
esbuild
configuration fromconfig/config.exs
and remove the dependency from thedeps
function in yourmix.exs
, and you are done!
what-did-we-do
What did we do?
You'll notice a bunch of files get created in /assets
, as well as some code changes in /lib
. This mostly follows from the recommended way of using esbuild plugins, which we need to make this work. You can read more about this here: https://hexdocs.pm/phoenix/asset_management.html#esbuild-plugins
In addition we commented out some things such as the esbuild
watcher configured in dev.exs
that won't be needed anymore, you can delete these comments if desired.
usage
Usage
Svelte components need to go into the assets/svelte/components
directory
- The
id
can be anything, but should be unique - Set the
name
of the Svelte component in thelive_component
. - Provide the
props
you want to use that should be reactive as a map to the props field
e.g. If your component is named assets/svelte/components/Example.svelte
:
def render(assigns) do
~H"""
<.live_component
module={LiveSvelte}
id="UniqueId"
name="Example"
props={%{number: @number}}
/>
"""
end
If your component is in a directory, for example assets/svelte/components/some-directory/SomeComponent.svelte
you need to include the directory in your name: some-directory/SomeComponent
.
examples
Examples
Examples can be found in the /examples
directory.
Create a Svelte component
<script>
// The number prop is reactive,
// this means if the server assigns the number, it will update in the frontend
export let number = 1
// pushEvent to ... push events to the server.
export let pushEvent
function increase() {
// This pushes the event over the websocket
// The last parameter is optional. It's a callback for when the event is finished.
// You could for example set a loading state until the event is finished if it takes a longer time.
pushEvent('set_number', { number: number + 1 }, () => {})
// Note that we actually never set the number in the frontend!
// We ONLY push the event to the server.
// This is the E2E reactivity in action!
// The number will automatically be updated through the LiveView websocket
}
function decrease() {
pushEvent('set_number', { number: number - 1 }, () => {})
}
</script>
<p>The number is {number}</p>
<button on:click={increase}>+</button>
<button on:click={decrease}>-</button>
Create a LiveView
# `/lib/app_web/live/live_svelte.ex`
defmodule AppWeb.SvelteLive do
use AppWeb, :live_view
def render(assigns) do
~H"""
<.live_component
module={LiveSvelte}
id="Example"
name="Example"
props={%{number: @number}}
/>
"""
end
def handle_event("set_number", %{"number" => number}, socket) do
{:noreply, assign(socket, :number, number)}
end
def mount(_params, _session, socket) do
{:ok, assign(socket, :number, 5)}
end
end
# `/lib/app_web/router.ex`
import Phoenix.LiveView.Router
scope "/", AppWeb do
...
live "/svelte", SvelteLive
...
end
preprocessor
Preprocessor
To use the preprocessor, install the desired preprocessor.
e.g. Typescript
cd assets && npm install --save-dev typescript
credits
Credits
Link to this section Summary
Link to this section Functions
Renders a Svelte component on the server.
attributes
Attributes
props
(:map
) - Defaults to%{}
.name
(:string
)rendered
(:boolean
) - Defaults tofalse
.