Guides

Facade Components

Facade Components are fake UI elements that get replaced once a third-party script loads.

Nuxt Scripts provides several Facade Components that you can use to speed up your app's performance.

Using them has trade-offs, but they can aid in improving the performance experience of your app.

What are Facade Components?

To render complex components using third-party scripts such as a Video embed, payment modal, or chat widget, we need many resources. Loading these while Nuxt is starting will slow down your app's performance.

However, if we delay loading the script until Nuxt is finished, we end up with harmful content layout shifts (CLS) and visual noise, leading to a poor user experience.

Facade Components aim to solve this by rendering a "fake" UI element that gets replaced once the third-party script loads.

By hooking into appropriate DOM events and providing user feedback, we can use these fake elements while still providing a great user experience.

What are the trade-offs in using Facade Components?

While the performance benefit is quite clear, there can be trade-off on user experience.

  • Flash of mismatched content: The fake UI element may not look like the final UI element, leading to a flash of mis-matched content. Only minimal styling is provided by Nuxt Scripts, you may need to tweak it to match your app's design.
  • Interactivity can break: Interactivity of the elements requires the script to load, if it doesn't load then you need to provide a fallback.
  • Accessibility Concerns: We need to provide clear a11y feedback to the user when the script is loading or fails to load.

Nuxt Scripts Facade Components

All Facade Components are headless components that wrap the relevant useScript<provider> composable. Minimal styling is provided within the docs to give you a starting point.

Best Practices in using Facade Components

Provide an error fallback

If the script fails to load, provide a fallback that informs the user of the failure and provides an alternative way to access the content.

<ScriptYouTubePlayer>
  <template #error>
    <UAlert color="red" title="YouTube player failed to load" description="Please refresh the page to try again." />
  </template>
</ScriptYouTubePlayer>

Provide a loading state with accessible feedback

When the script is loading, provide a loading state that informs the user that the content is loading.

The ScriptLoadingIndicator component is provided by Nuxt Scripts to help with this and provides a11y feedback.

<ScriptYouTubePlayer>
  <template #loading>
  <ScriptLoadingIndicator />
  </template>
</ScriptYouTubePlayer>

Choose the triggering event wisely

The Facade Components are pre-configured for the best general performance, but you can customize the triggering event to better match your app's needs.

The best triggers are one that require explicit user interaction such as a click. Loading on hover may cause user experience issues with subsequent events being lost such as clicks.

Facade Components API

All Facade Components share a similar API.

Props

Slots

The component provides minimal UI by default, only enough to be functional and accessible. There are a number of slots for you to customize the components however you need.

  • default - Content to always display with the component.
<template>
  <ScriptYouTubePlayer>
    <div class="bg-blue-500 text-white p-5">
      Youtube!
    </div>
  </ScriptYouTubePlayer>
</template>
  • loading - The content to display only while the script is loading.
<template>
  <ScriptYouTubePlayer>
    <template #loading>
      <ScriptLoadingIndicator />
    </template>
  </ScriptYouTubePlayer>
</template>
  • awaitingLoad - The content to display only while the script is waiting to load.
<template>
  <ScriptYouTubePlayer>
    <template #awaitingLoad>
    <div class="bg-blue-500 text-white p-5">
      Click to play!
    </div>
    </template>
  </ScriptYouTubePlayer>
</template>
  • error - The content to display if the script fails to load.
<template>
  <ScriptYouTubePlayer>
    <template #error>
      <UAlert color="red" title="YouTube player failed to load" description="Please refresh the page to try again." />
    </template>
  </ScriptYouTubePlayer>
</template>

Events

  • ready - Emitted when the script has loaded. Gives you access to the underlying script API.
  • error - Emitted when the script fails to load.