LiveVue 1.0
Examples Custom Encoder

Custom Encoder

Control how structs are encoded to JSON using the LiveVue.Encoder protocol. Derive for simple cases, implement custom logic when needed.

What this example shows

1
@derive
Simple encoder derivation
2
defimpl
Custom encode function
3
Options
Runtime encoding behavior
Encoder.vue
<script setup lang="ts">
type Business = { name: string; industry: string }
type UserProfile = { name: string; avatar_url: string; business: Business }

const props = defineProps<{
  profile: UserProfile
  profile_original: UserProfile
}>()
</script>

<template>
  <div class="space-y-4">
    <div class="card bg-base-200 p-4">
      <div class="text-xs text-neutral mb-3">Default encoding</div>
      <div class="flex items-center gap-3">
        <img :src="props.profile.avatar_url" class="w-12 h-12 rounded-full" />
        <div>
          <div class="font-medium">{{ props.profile.name }}</div>
          <div class="text-neutral text-sm">
            {{ props.profile.business.name }}
          </div>
        </div>
      </div>
      <div class="mt-3 text-xs font-mono text-neutral truncate">
        Url: {{ props.profile.avatar_url.slice(28, 100) }}
      </div>
    </div>

    <div class="card bg-base-200 p-4">
      <div class="text-xs text-neutral mb-3">With <code class="text-secondary">avatar: :original</code></div>
      <div class="flex items-center gap-3">
        <img :src="props.profile_original.avatar_url" class="w-12 h-12 rounded-full" />
        <div>
          <div class="font-medium">{{ props.profile_original.name }}</div>
          <div class="text-neutral text-sm">
            {{ props.profile_original.business.name }}
          </div>
        </div>
      </div>
      <div class="mt-3 text-xs font-mono text-neutral truncate">
        Url: {{ props.profile_original.avatar_url.slice(28, 100) }}
      </div>
    </div>
  </div>
</template>

How it works

1 Derive for simple structs

Use @derive LiveVue.Encoder to automatically encode all struct fields. Add only: or except: to control which fields are included.

defmodule Business do
  @derive LiveVue.Encoder
  defstruct [:name, :industry]
end

2 Custom implementations with options

Implement the protocol directly when you need custom encoding logic. The opts parameter lets you change behavior at runtime.

defimpl LiveVue.Encoder, for: UserProfile do
  def encode(profile, opts) do
    avatar_url =
      if Keyword.get(opts, :avatar) == :original,
        do: profile.avatar_original_url,
        else: profile.avatar_url

    %{
      name: profile.name,
      avatar_url: avatar_url,
      business: encode(profile.business, opts)
    }
  end
end

3 Pass options when encoding

Call LiveVue.Encoder.encode/2 explicitly in your template to pass custom options. This lets you control encoding per-prop.

<.vue
  profile={@profile}
  profile_with_original_avatar={LiveVue.Encoder.encode(@profile, avatar: :original)}
  v-component="UserProfile"
  v-socket={@socket}
/>

4 Nested structs are encoded recursively

When encoding nested structs, call LiveVue.Encoder.encode/2 on nested values to ensure they're properly encoded. Options are passed through.

business: LiveVue.Encoder.encode(profile.business, opts)
Next up: File Upload
View example →