nuxt / nuxt/image

Img call signature does not accept configured providers other than default

Open
#2,174 0 comments 6 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
1.5k
Forks
331
Avg merge
19h 52m
Merged PRs (30d)
9

Description

Environment
  • @nuxt/image: v2.0.0
  • Nuxt: 4.x
  • TypeScript: strict mode
Description

The Img interface's call signature hardcodes ImageOptions without a generic parameter, which defaults to DefaultProvider (resolved from ProviderDefaults['provider']). This means the provider field in the options argument only accepts the default provider (e.g. "ipx"), even when other providers are properly configured.

Generated types (.nuxt/image/providers.d.ts):

interface ProviderDefaults {
  provider: "ipx"
}
interface ConfiguredImageProviders {
  "directus": ImageProviders["directus"]
  "ipx": ImageProviders["ipx"]
}

Img interface (module.d.ts):

type DefaultProvider = ProviderDefaults extends Record<'provider', unknown> ? ProviderDefaults['provider'] : never;

interface ImageOptions<Provider extends keyof ConfiguredImageProviders = DefaultProvider> {
    provider?: Provider; // defaults to "ipx"
}

interface Img {
    (source: string, modifiers?: ImageOptions['modifiers'], options?: ImageOptions): ResolvedImage['url'];
    //                                                                ^^^^^^^^^^^^
    //                        ImageOptions without generic = ImageOptions<"ipx">, so provider?: "ipx"
}
Reproduction

Configure a non-default provider (e.g. directus) in nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  image: {
    providers: {
      directus: {
        provider: 'directus',
        options: {
          baseURL: 'https://example.com/assets/',
        },
      },
    },
  },
})

Then use useImage() with that provider:

const img = useImage();
const url = img('some-id', {}, { provider: 'directus' });
//                                          ^^^^^^^^^^
// TS2322: Type '"directus"' is not assignable to type '"ipx"'
Expected behavior

The provider option in Img's call signature should accept any key from ConfiguredImageProviders, not just the default provider.

Suggested fix

Make the Img interface generic or widen the provider type to accept all configured providers:

interface Img {
    (source: string, modifiers?: ImageOptions['modifiers'], options?: ImageOptions<keyof ConfiguredImageProviders>): ResolvedImage['url'];
}
Workaround
import type { ImageOptions } from '@nuxt/image';

const directusOptions = { provider: 'directus' } as unknown as ImageOptions;
const url = img('some-id', {}, directusOptions);

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in module.d.ts at the Img call signature and review the ImageOptions and ConfiguredImageProviders types shown in the issue. Reproduce the strict TypeScript error with the directus provider example, then verify that the call accepts configured non-default providers while retaining the existing default-provider behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
nuxt, typescript
Domain
frontend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.