Changelog

View Source

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

0.7.3 - 2025-08-18

Improvements

  • Added fallback type definitions for phoenix_live_view versions < 1.1 that don't export TypeScript types
  • Enhanced type compatibility with conditional DOM types that adapt to server vs client environments
  • Improved TypeScript development experience with better type safety across different phoenix_live_view versions

0.7.2 - 2025-08-12

Improvements

  • Docs links are now working in both Github and docs #66

Bug fixes

  • Types for $live should now be correctly resolved

0.7.1 - 2025-07-30

๐Ÿ› Bugfixes

  • Fixed useLiveUpload composable to properly handle change event dispatching for addFiles - now auto uploads for drag and drop should be working
  • addFiles now accepts DataTransfer objects directly
  • diff algorithm correctly handles time and date values - they're maps internally, but should be diffed as strings.

๐Ÿงช Testing

  • Added E2E tests for drag and drop functionality

0.7.0 - 2025-07-29

๐Ÿš€ New Composable: useLiveUpload

  • File Upload Composable: Added useLiveUpload() composable for seamless Vue integration with Phoenix LiveView file uploads
    • Provides reactive upload state management with progress tracking and metadata
    • Automatic DOM element management for file inputs
    • Built-in support for drag-and-drop file handling
    • Integration with LiveView's upload validation and submission system
    • TypeScript support with full type definitions for upload configurations
    • Simplifies complex upload workflows with a declarative Vue-friendly API

๐Ÿงช Testing Improvements

  • Frontend Test Suite: Added comprehensive test suite for frontend TypeScript code using Vitest framework
    • Tests for JSON Patch functionality (assets/js/live_vue/jsonPatch.ts) with 36 test cases covering all operations
    • Test configuration with jsdom environment for DOM testing
    • Coverage includes edge cases like escaped characters, deep cloning, and complex patch sequences
  • End-to-End Test Suite: Added comprehensive E2E test suite using Playwright framework (#64)
    • Tests for Vue component rendering, props passing, event emission, and LiveView/Vue synchronization
    • 5 test suites covering basic functionality, navigation, events, prop diffs, and file uploads
    • Test server setup with dedicated Phoenix endpoint for isolated testing
    • Utilities for LiveView/Vue synchronization and server-side code execution
  • Separate CI Workflows: Split testing into dedicated workflows for better separation of concerns
    • Frontend CI: Tests TypeScript code across Node.js versions 20, 22, and 24 (LTS and current stable)
    • Elixir CI: Focused purely on Elixir/OTP matrix testing without redundant frontend test runs
  • New Mix Commands: Added mix assets.test alias for running frontend tests alongside existing npm scripts
    • npm test - Run tests once
    • npm run test:watch - Run tests in watch mode
    • npm run test:ui - Run tests with interactive UI
    • npm run e2e:test - Run E2E tests
    • npm run e2e:test:headed - Run E2E tests with browser UI
    • npm run e2e:test:debug - Run E2E tests in debug mode

0.6.1 - 2025-07-24

Fixes ๐Ÿ›

  • correctly encode props in SSR mode
  • correctly handle diffs for nil values in props
  • added package version to the package.json

0.6.0 - 2025-07-22

โœจ Features and Improvements

  • JSON Patch Diffs for Props: LiveVue now uses JSON Patch operations to send only the minimal differences when props change, dramatically reducing WebSocket payload sizes. Instead of sending entire prop objects, only the specific fields that changed are transmitted using RFC 6902 JSON Patch format. This optimization works seamlessly with complex nested structures, lists, and custom structs through the LiveVue.Encoder protocol. It's possible to skip diffs by setting v-diff to false on the component or by setting config :live_vue, enable_props_diff: false in your config. (#60)
  • New useLiveNavigation Composable: A new useLiveNavigation composable has been added for programmatic navigation, mirroring the functionality of live_patch and live_redirect. (#59).
  • New useLiveEvent Composable: A new useLiveEvent composable has been added to simplify listening to server-pushed events. It automatically manages event listener lifecycle, reducing boilerplate and preventing memory leaks (#58).
  • New Link Component: A new <Link> Vue component has been added to simplify live_patch and live_redirect navigation within your Vue components. (#47).
  • TypeScript by Default: The client-side entrypoint at assets/vue/index.ts is now a TypeScript file by default, improving type safety and the development experience out of the box.
  • $live Template Property: The LiveView hook instance is now automatically available in all Vue templates as the $live property, providing a convenient alternative to useLiveVue(). The property is now also fully typed, providing autocompletion and type checking in your editor. (#56).
  • Documentation Overhaul: The documentation has been completely rewritten and expanded. It now includes comprehensive guides on architecture, basic and advanced usage, a full client-side API reference, a component reference, and much more. (#49)
  • Testing Utilities: The new LiveVue.Test module provides helpers to inspect Vue component configuration (props, slots, event handlers) within your LiveView tests, making it easier to write assertions. (#46)
  • GitHub CI: A new GitHub Actions workflow has been added to run tests automatically.

โฌ†๏ธ Migration Guide

This version transitions the default client-side setup to TypeScript and renames ~V sigil to ~VUE. If you have an existing assets/vue/index.js, follow these steps to upgrade:

  1. Rename and replace index.js:

    • Delete your existing assets/vue/index.js.
    • Create a new file at assets/vue/index.ts with the following content:
    // polyfill recommended by Vite https://vitejs.dev/config/build-options#build-modulepreload
    import "vite/modulepreload-polyfill"
    import { Component, h } from "vue"
    import { createLiveVue, findComponent, type LiveHook, type ComponentMap } from "live_vue"
    
    // needed to make $live available in the Vue component
    declare module "vue" {
      interface ComponentCustomProperties {
        $live: LiveHook
      }
    }
    
    export default createLiveVue({
      // name will be passed as-is in v-component of the .vue HEEX component
      resolve: name => {
        // we're importing from ../../lib to allow collocating Vue files with LiveView files
        // eager: true disables lazy loading - all these components will be part of the app.js bundle
        // more: https://vite.dev/guide/features.html#glob-import
        const components = {
          ...import.meta.glob("./**/*.vue", { eager: true }),
          ...import.meta.glob("../../lib/**/*.vue", { eager: true }),
        } as ComponentMap
    
        // finds component by name or path suffix and gives a nice error message.
        // `path/to/component/index.vue` can be found as `path/to/component` or simply `component`
        // `path/to/Component.vue` can be found as `path/to/Component` or simply `Component`
        return findComponent(components as ComponentMap, name)
      },
      // it's a default implementation of creating and mounting vue app, you can easily extend it to add your own plugins, directives etc.
      setup: ({ createApp, component, props, slots, plugin, el }) => {
        const app = createApp({ render: () => h(component as Component, props, slots) })
        app.use(plugin)
        // add your own plugins here
        // app.use(pinia)
        app.mount(el)
        return app
      },
    })
  2. Update tsconfig.json: Add vue/index.ts to the include array in your assets/tsconfig.json file. The final result should look similar to this:

    {
      "compilerOptions": {
        // ...
      },
      "include": ["js/**/*.ts", "js/**/*.js", "js/**/*.tsx", "vue/**/*.vue", "vue/index.ts"]
    }

๐Ÿ› Bug Fixes

  • SSR Attribute Rendering: Fixed a bug where the data-ssr attribute was not being rendered correctly as a boolean true or false in the final HTML.

Housekeeping

  • Optional Floki Dependency: floki is now an optional dependency, only required if you use the new testing utilities.
  • Dependency Updates: NPM dependencies have been updated to address security vulnerabilities.
  • Dropped Elixir 1.12 Support: Support for Elixir 1.12 has been removed to align with Phoenix LiveView's supported versions.

0.5.7 - 2024-12-04

Fixes

  • Fix the useLiveVue hook typings to show all available functions and properties.

0.5.6 - 2024-11-27

Improvements

  • Much better typing for the library #41. Big thanks to @francois-codes for the contribution!
  • Added worker option to vite.config.js, and added instruction how to deal with typescript error #45

0.5.5 - 2024-11-14

Fixes

  • Slots are now rendered correctly in SSR #39

0.5.4 - 2024-11-13

Fixed

  • added type: module to package.json in live_vue to fix the older nodejs module resolution issue #36

0.5.3 - 2024-11-12

Fixed

  • Added explicit extensions to all JS imports. It should fix some issues with module resulution. #36

0.5.2 - 2024-10-08

Changed

  • Added hint to pass --silent flag to npm watcher in INSTALLATION.md. It prevents npm from printing executed command which is not useful and makes output messy.
config :my_app, MyAppWeb.Endpoint,
  # ...
  watchers: [
    npm: ["--silent", "run", "dev", cd: Path.expand("../assets", __DIR__)]
  ]

0.5.1 - 2024-10-08

Fixed

  • Fixed a bug where the server was not preloading the correct assets for the Vue components. It happened because CursorAI "skipped" important part of the code when migrating to the TypeScript ๐Ÿ˜…

0.5.0 - 2024-10-08

Changed

  • Migrated the project to TypeScript ๐Ÿ’œ #32
  • Added createLiveVue entrypoint to make it easier to customize Vue app initialization

Deprecations

  • assets/vue/index.js should export app created by createLiveVue(), not just available components. See migration below.

Migration

In assets/js/app.js, instead of:

export default {
  ...import.meta.glob("./**/*.vue", { eager: true }),
  ...import.meta.glob("../../lib/**/*.vue", { eager: true }),
}

use:

// polyfill recommended by Vite https://vitejs.dev/config/build-options#build-modulepreload
import "vite/modulepreload-polyfill"
import { h } from "vue"
import { createLiveVue, findComponent } from "live_vue"

export default createLiveVue({
  resolve: name => {
    const components = {
      ...import.meta.glob("./**/*.vue", { eager: true }),
      ...import.meta.glob("../../lib/**/*.vue", { eager: true }),
    }

    // finds component by name or path suffix and gives a nice error message.
    // `path/to/component/index.vue` can be found as `path/to/component` or simply `component`
    // `path/to/Component.vue` can be found as `path/to/Component` or simply `Component`
    return findComponent(components, name)
  },
  setup: ({ createApp, component, props, slots, plugin, el }) => {
    const app = createApp({ render: () => h(component, props, slots) })
    app.use(plugin)
    app.mount(el)
    return app
  },
})

then, in assets/js/app.js, instead of:

import components from "./vue"

simply do

import { getHooks } from "live_vue"
import liveVueApp from "./vue"
// ...

const hooks = { ...getHooks(liveVueApp) }

If you had any custom initialization code, you have to move it to createLiveVue().setup() function.

Fixed

  • Nicely formatted JS error stracktraces during SSR commit
  • Previously initializeVueApp was not working in SSR mode, since it was declared in app.js which couldn't be imported by server bundle. Now it's in a separate file as createLiveVue().setup() and can be imported by both client and server bundles.

0.4.1 - 2024-08-30

Changed

  • Improved pathToFullPathAndFilename to work with index.vue files. Now ../ComponentName/index.vue can be referenced as ComponentName #23

0.4.0 - 2024-06-12

New feature

  • Support for custom Vue instance initialization #13 by @morfert

0.3.9 - 2024-06-07

0.3.8 - 2024-06-01

Fixed

  • Invalid live_vue import in copied package.json (file:../.. -> file:../deps/live_vue)
  • Changed useLiveVue inject key from Symbol() to _live_vue string, so it's working if Vite does a reload and Symbol is re-evaluated.

Added

  • Added live_vue, phoenix, phoenix_html and phonenix_live_vue to vite optimizeDeps.include config options. It should pre-bundle these packages in development, making it consistent with packages imported from node_modules and improve DX.
  • Added initial typescript definitions. Apparently it's enough to name them <filename>.d.mts, so I've created them both for index.mjs and server.mjs

0.3.7 - 2024-05-26

Changed

  • Added a Mix.Task to make JS file setup more straightforward and cross-platform #11. Contribution by @morfert ๐Ÿ”ฅ
  • Installation instruction was moved to the separate file
  • Package.json was added to files automatically copied from live_vue when using mix live_vue.setup

Fixed

  • Removed build: {modulePreload: { polyfill: false }} from vite.config.js as it made it impossible to use vite/modulepreload-polyfill. To migrate: please remove that line from yours vite.config.js. Fixed #12

0.3.6 - 2024-05-24

Fixed

0.3.5 - 2024-05-24

Changed

  • Removed body-parser dependency from live_vue. Should fix #9

0.3.4 - 2024-05-22

Fixed

  • Props are correctly updated when being arrays of structs

0.3.3 - 2024-05-22

Fixed

  • Javascript imports were mixed - vitePlugin.js was using CJS, rest was using ESM. Now it's explicit by adding ".mjs" extension.
  • Removed :attr declarations for <.vue> component to avoid warnings related to unexpected props being passed to :rest attribute #8

0.3.2 - 2024-05-19

Fixed

  • Hot reload of CSS when updating Elixir files

0.3.1 - 2024-05-17

Changed

  • Simplified assets/vue/index.js file - mapping filenames to keys is done by the library. Previous version should still work.

0.3.0 - 2024-05-17

CHANGED

  • removed esbuild from live_vue, package.json points directly to assets/js/live_vue
  • added support to lazy loading components. See more in README. To migrate, ensure all steps from installation are up-to-date.

0.2.0 - 2024-05-17

QoL release

Added

  • @ added to Vite & typescript paths. To migrate, see assets/copy/tsconfig.json and assets/copy/vite.config.js
  • Added Vite types to tsconfig.json to support special imports, eg. svg. To migrate, add "types": ["vite/client"].
  • Added possibility to colocate Vue files in lib directory. To migrate, copy assets/copy/vue/index.js to your project.

Changed

  • Adjusted files hierarchy to match module names
  • Publishing with expublish

[0.1.0] - 2024-05-15

Initial release

  • Start of the project
  • End-To-End Reactivity with LiveView
  • Server-Side Rendered (SSR) Vue
  • Tailwind Support
  • Dead View Support
  • Vite support