Skip to content

Releases: salesforce/lwc

v7.0.0

19 Jun 21:10
1a83a8d
Compare
Choose a tag to compare

LWC v7.0.0 contains breaking changes. Please read carefully below if you are upgrading from v6.

If you are upgrading from v5, please upgrade to v6 first.

Note

LWC v7 corresponds to Salesforce release Winter '25 (API version 62).

New features

Summary of breaking changes

Breaking changes

Class object binding

Note

On the Salesforce Lightning platform, this change only applies to components with an API version of 62 or above.

Class object binding is a new feature that makes it more ergonomic to render class attributes in your LWC components. As part of this feature, class rendering has changed for some uncommon use cases.

If you are using a dynamic class in your template:

<template>
  <div class={myClass}></div>
</template>

Then the rendering of this class may change if you were previously defining myClass as something other than a string, null, or undefined.

For example, consider if myClass is a boolean:

export default class extends LightningElement {
  myClass = false
}

Old behavior:

This renders:

<div class="false"></div>

New behavior:

<div class=""></div>

This change applies to booleans, numbers, functions, arrays, and objects. Below is a table summarizing the change:

Type Example Rendered (old) Rendered (new)
Boolean true class="true" class=""
Number 1 class="1" class=""
Function () => {} class="() => {}" class=""
Array ["a", "b"] class="a,b" class="a b"
Object { a: true } class="[object Object]" class="a"

In short:

  • Booleans, numbers, and functions are no longer directly stringified, but are stripped instead.
  • Arrays and objects are no longer stringified, but instead follow class object binding semantics.

This may break a component if it is using a CSS selector like these:

.false {}
.true {}
[class="1"] {}

Or if it is using querySelector or other traversal techniques that rely on the class name:

this.template.querySelector('.false')
this.template.querySelector('.true')
this.template.querySelector('[class="1"]')

In rare cases, this can also cause breakages across component boundaries. For example, if you have a global stylesheet relying on light DOM or synthetic shadow DOM, and thus the ability to pierce inside of components you don't own, then the above CSS selectors would break in that case as well.

To resolve any breakages:

This change may also require updating snapshots, e.g. in Jest tests.

New this.style property

Note

On the Salesforce Lightning platform, this change only applies to components with an API version of 62 or above.

Components can now access their CSSStyleDeclaration using this.style:

renderedCallback() {
  this.style.color = 'red'
}

This is a breaking change if the component uses this.style as an expando:

renderedCallback() {
  if (!this.style) {
    this.style = "foo"
  }
}

In the above case, the component author may assume that this.style is initially undefined, and then set it to a new value ("foo"). After this change, the above code will not work as expected, because this.style is initially truthy rather than undefined.

To resolve this, set a class property on the component, initialized to undefined, rather than using an expando:

+ style = undefined
  
  renderedCallback() {
    if (!this.style) {
      this.style = "foo"
    }
  }

You may also rename your this.style expando to something else (e.g. this.customStyle).

New this.hostElement property

Note

On the Salesforce Lightning platform, this change only applies to components with an API version of 62 or above.

Components can now access this.hostElement as a convenient alternative to this.template.host:

renderedCallback() {
  console.log(this.template.host) // <x-component>
  console.log(this.hostElement)   // <x-component>
}

Additionally, this works in light DOM components to access the "host" element (similar to the :host CSS pseudo-class in light DOM scoped styles). This provides an ergonomic way to access the root HTMLElement object in either light DOM or shadow DOM components.

Similar to the new this.style property, this is a breaking change if you are using this.hostElement already as an expando. Refer to the this.style release notes for a resolution.

Improved TypeScript types

Note

This change only applies to component authors using TypeScript, which is not yet fully supported.

The TypeScript definitions for the lwc package are greatly improved, to more closely match the ground truth of the actual APIs for LightningElement, createElement, etc. at runtime. You may need to adjust your TypeScript code or version to adapt to the new typings.

Summary

  • The minimum supported version of TypeScript is v5.4.5.
  • The only supported compiler target is "ESNext".
  • ContextValue has been renamed to WireContextValue.
  • ContextConsumer has been renamed to WireContextConsumer.
  • Contextualizer has been renamed to WireContextProvider.
  • StylesheetFactory has been renamed to Stylesheet.
  • StylesheetFactories has been renamed to Stylesheets.
  • StringKeyedRecord has been removed. Instead, use the type Record<string, any>.
  • ShadowSupportMode has been removed. Instead, use the string values "any", "reset", or "native".
  • WireAdapter is now a generic type with a default type parameter.
  • WireAdapterConstructor is now a generic type with a default type parameter.
  • All decorators can now be used with the new decorator implementation introduced in TypeScript v5 as well as the old, experimental implementation.
  • this.template is now possibly null, reflecting the state for components using light DOM.
  • this.template.host in a LightningElement is now typed as HTMLElement, rather than the broader Element.
  • The return type of createElement has been updated to reflect the fact that the element created contains the @api-decorated props from the component definition.
    • A new helper type, LightningHTMLElement, has been introduced to provide an easy way of accessing the return type.
      const cmp: LightningHTMLElement<MyComponent> = createElement('my-component', { is: MyComponent });
    • WARNING: Due to limitations of TypeScript, this new type incorrectly contains all props defined on the component, not just decorated props. Only decorated props are accessible at runtime.
  • Importing from "lwc" now provides module definitions for HTML/CSS imports. The module definitions are also available by directly importing a new package, @lwc/types.

Common breakages and fixes

Breakage Fix
HTML imports (import myComponent from './my-component.html') Import @lwc/types or lwc/types somewhere in your project. I.e.: import '@lwc/types'.
StringKeyedRecord Replace with Record<string, any> or similar.
ContextValue Renamed to WireContextValue, but it's really just Record<string, any>, so you could use a more precise type instead.
ContextConsumer Renamed to WireContextConsumer
Contextualizer Renamed to WireContextProvider
createElement Use type assertion to cast to HTMLElement & MyComponentApiDecoratedProps. You have to define your own interface to get the @api decorated props, because TypeScript can't detect that. (You can use your component class, but that includes all component and LightningElement props, not just component @api decorated props, so it's not ideal.)
this.template is possibly undefined Use [optional chaining](http...
Read more

v7.0.0 (prerelease)

18 Jun 22:54
eb91679
Compare
Choose a tag to compare
v7.0.0 (prerelease) Pre-release
Pre-release

LWC v7.0.0 contains breaking changes. Please read carefully below if you are upgrading from v6.

If you are upgrading from v5, please upgrade to v6 first.

Note

LWC v7 corresponds to Salesforce release Winter '25 (API version 62).

New features

Summary of breaking changes

Breaking changes

Class object binding

Note

On the Salesforce Lightning platform, this change only applies to components with an API version of 62 or above.

Class object binding is a new feature that makes it more ergonomic to render class attributes in your LWC components. As part of this feature, class rendering has changed for some uncommon use cases.

If you are using a dynamic class in your template:

<template>
  <div class={myClass}></div>
</template>

Then the rendering of this class may change if you were previously defining myClass as something other than a string, null, or undefined.

For example, consider if myClass is a boolean:

export default class extends LightningElement {
  myClass = false
}

Old behavior:

This renders:

<div class="false"></div>

New behavior:

<div class=""></div>

This change applies to booleans, numbers, functions, arrays, and objects. Below is a table summarizing the change:

Type Example Rendered (old) Rendered (new)
Boolean true class="true" class=""
Number 1 class="1" class=""
Function () => {} class="() => {}" class=""
Array ["a", "b"] class="a,b" class="a b"
Object { a: true } class="[object Object]" class="a"

In short:

  • Booleans, numbers, and functions are no longer directly stringified, but are stripped instead.
  • Arrays and objects are no longer stringified, but instead follow class object binding semantics.

This may break a component if it is using a CSS selector like these:

.false {}
.true {}
[class="1"] {}

Or if it is using querySelector or other traversal techniques that rely on the class name:

this.template.querySelector('.false')
this.template.querySelector('.true')
this.template.querySelector('[class="1"]')

In rare cases, this can also cause breakages across component boundaries. For example, if you have a global stylesheet relying on light DOM or synthetic shadow DOM, and thus the ability to pierce inside of components you don't own, then the above CSS selectors would break in that case as well.

To resolve any breakages:

This change may also require updating snapshots, e.g. in Jest tests.

New this.style property

Note

On the Salesforce Lightning platform, this change only applies to components with an API version of 62 or above.

Components can now access their CSSStyleDeclaration using this.style:

renderedCallback() {
  this.style.color = 'red'
}

This is a breaking change if the component uses this.style as an expando:

renderedCallback() {
  if (!this.style) {
    this.style = "foo"
  }
}

In the above case, the component author may assume that this.style is initially undefined, and then set it to a new value ("foo"). After this change, the above code will not work as expected, because this.style is initially truthy rather than undefined.

To resolve this, set a class property on the component, initialized to undefined, rather than using an expando:

+ style = undefined
  
  renderedCallback() {
    if (!this.style) {
      this.style = "foo"
    }
  }

You may also rename your this.style expando to something else (e.g. this.customStyle).

New this.hostElement property

Note

On the Salesforce Lightning platform, this change only applies to components with an API version of 62 or above.

Components can now access this.hostElement as a convenient alternative to this.template.host:

renderedCallback() {
  console.log(this.template.host) // <x-component>
  console.log(this.hostElement)   // <x-component>
}

Additionally, this works in light DOM components to access the "host" element (similar to the :host CSS pseudo-class in light DOM scoped styles). This provides an ergonomic way to access the root HTMLElement object in either light DOM or shadow DOM components.

Similar to the new this.style property, this is a breaking change if you are using this.hostElement already as an expando. Refer to the this.style release notes for a resolution.

Improved TypeScript types

Note

This change only applies to component authors using TypeScript, which is not yet fully supported.

  • The minimum supported version of TypeScript is v5.4.5.
  • The only supported compiler target is "ESNext".
  • ContextValue has been renamed to WireContextValue.
  • ContextConsumer has been renamed to WireContextConsumer.
  • Contextualizer has been renamed to WireContextProvider.
  • StylesheetFactory has been renamed to Stylesheet.
  • StylesheetFactories has been renamed to Stylesheets.
  • StringKeyedRecord has been removed. Instead, use the type Record<string, any>.
  • ShadowSupportMode has been removed. Instead, use the string values "any", "reset", or "native".
  • WireAdapter is now a generic type with a default type parameter.
  • WireAdapterConstructor is now a generic type with a default type parameter.
  • All decorators can now be used with the new decorator implementation introduced in TypeScript v5 as well as the old, experimental implementation.
  • this.template is now possibly null, reflecting the state for components using light DOM.
  • this.template.host in a LightningElement is now typed as HTMLElement, rather than the broader Element.
  • The return type of createElement has been updated to reflect the fact that the element created contains the @api-decorated props from the component definition.
    • A new helper type, LightningHTMLElement, has been introduced to provide an easy way of accessing the return type.
      const cmp: LightningHTMLElement<MyComponent> = createElement('my-component', { is: MyComponent });
    • WARNING: Due to limitations of TypeScript, this new type incorrectly contains all props defined on the component, not just decorated props. Only decorated props are accessible at runtime.
  • Importing from "lwc" now provides module definitions for HTML/CSS imports. The module definitions are also available by directly importing a new package, @lwc/types.

@lwc/template-compiler API changes

Note

This change only affects direct consumers of the @lwc/template-compiler npm package, who are using the compile API.

Due to a refactoring of the @lwc/compiler and @lwc/template-compiler packages, the @lwc/template-compiler compile function now requires the component's file name (i.e. the namespace and name options) when compiling the template.

To resolve the breaking change, add the new options. For example:

import { compile } from '@lwc/template-compiler'

compile({
  ...previousOptions,
  // Assuming the component is `<x-foo>`:
  namespace: 'x',
  name: 'foo',
})

v6.7.2

14 Jun 19:25
1581bc6
Compare
Choose a tag to compare

What's Changed

Full Changelog: v6.7.1...v6.7.2

v6.7.1

12 Jun 17:50
e29dd16
Compare
Choose a tag to compare

What's Changed

Full Changelog: v6.7.0...v6.7.1

v6.7.0

11 Jun 20:52
3690b9e
Compare
Choose a tag to compare

What's Changed

  • feat: expose the registered component class as a const declaration to allow hmr hooks for class @W-15890472 by @ravijayaramappa in #4271
  • fix: skip hydration validation when static parts have static classes by @jmsjtu in #4278

Full Changelog: v6.6.7...v6.7.0

v6.6.7

10 Jun 19:15
6bed698
Compare
Choose a tag to compare

What's Changed

  • fix(rollup-plugin): allow any implicit HTML import from any kind of script file @W-15941938 by @wjhsf in #4261
  • chore: release v6.6.7 by @rax-it in #4274
  • chore: nucleus release v.6.6.7 by @rax-it in #4276

Full Changelog: v6.6.6...v6.6.7

v6.6.6

05 Jun 20:40
c9aa701
Compare
Choose a tag to compare

What's Changed

Full Changelog: v6.6.5...v6.6.6

v6.4.5

05 Jun 20:34
4e09530
Compare
Choose a tag to compare

What's Changed

  • fix: prevent prematurely cloning light dom slot vnodes (summer24) by @jmsjtu in #4262
  • chore: release v6.4.5 by @jmsjtu in #4264

Full Changelog: v6.4.4...v6.4.5

v6.6.5

30 May 15:51
41ae268
Compare
Choose a tag to compare

What's Changed

Full Changelog: v6.6.4...v6.6.5

v6.4.4

30 May 21:04
ca59ea4
Compare
Choose a tag to compare

What's Changed

Full Changelog: v6.4.3...v6.4.4