Static imports of user-specific scoped modules, such as @salesforce/user/*
, are not supported in LWC components marked with lightning__ServerRenderable
or lightning__ServerRenderableWithHydration
.
The following Salesforce scoped modules are deprecated when using Server-Side Rendering (SSR):
@salesforce/user/*
@salesforce/userPermission/*
@salesforce/customPermission/*
To replace these deprecated modules, use dynamic imports to fetch the necessary data on-demand. This ensures that SSR can run without issues and user-specific data is loaded appropriately after hydration on the client-side. For more details, refer to the guide on Adding Dynamic Data to LWR Sites.
If your component relies on one of these scoped modules, follow these best practices:
-
On the Server (SSR):
- Render a placeholder during SSR to avoid negatively impacting web vitals.
-
On the Client (after Hydration):
- Dynamically import the module after hydration to avoid SSR issues.
<template>
<template lwc:if="{userId}"><c-user-profile user-id="{userId}"></c-user-profile></template>
<!-- Rendering a placeholder avoids layout shifts on the client when the user ID is loaded -->
<template lwc:else><c-user-placeholder></c-user-placeholder></template>
</template>
Example of incorrect code:
import { LightningElement } from 'lwc';
import Id from '@salesforce/user/Id';
export default class UserProfile extends LightningElement {
userId = Id;
}
Example of correct code:
import { LightningElement } from 'lwc';
export default class UserProfile extends LightningElement {
userId;
async connectedCallback() {
if (!import.meta.env.SSR) {
// Only load user-specific scoped modules on the client
// This logic requires hydration of the component
this.userId = await import('@salesforce/user/Id');
}
}
}