# Recipes
Practical patterns for `@revenexx/storage-model-viewer`. See the [README](../README.md)
for the full attribute and engine reference.
## A product gallery slide (Nuxt, three.js)
Toggle the main gallery area between still images and the interactive model. Used by the
Cover storefront's `ProductDetailImageGallery`.
```vue
```
## A double-click viewer (Cockpit, three.js)
Open the model from a media grid. The dialog body provides a definite height.
```vue
```
## AR in Nuxt
The AR engine (`engine="model-viewer"`) needs `@google/model-viewer` in the client bundle.
Vite's scanner does **not** follow the package's nested dynamic import, so force it:
```ts
// app/plugins/model-viewer.client.ts
import '@google/model-viewer' // <-- forces it into the bundle + registers it
export default defineNuxtPlugin(async () => {
await import('@revenexx/storage-model-viewer')
})
```
```ts
// nuxt.config.ts
export default defineNuxtConfig({
build: { transpile: ['@google/model-viewer'] },
vue: { compilerOptions: { isCustomElement: t => t === 'rx-model-viewer' || t === 'model-viewer' } },
})
```
```vue
```
- **Android** uses the `.glb` (`src`); make sure it is metre-scaled so AR places it at real size.
- **iOS** uses the USDZ (`ios-src`); without it, no iOS AR button.
- Add `@google/model-viewer` as a direct dependency of the consuming app.
## Background & framing
```html
```
The three.js engine frames the whole model automatically; don't pass `camera-orbit` unless
you need a specific start angle (a custom orbit with `auto` radius can mis-frame small,
metre-scale parts).
## Plain HTML / any framework
```html
```
## Troubleshooting
See the [README troubleshooting table](../README.md#troubleshooting). The most common issue
is a **collapsed canvas** from a container without a definite height.