Skip to main content
Wildo.ai Coming soon

Files and storage

Give file selection a shared application default

A frontend provider supplies reusable picker defaults while individual fields keep their own requirements.

A file chooser offers a device and a connected library as sources.

Give file selection a shared application default

File selection should feel consistent across an application. Wildo gives standard file fields and custom upload views a shared provider contract for accepted types, size and selection count.

A field can state its own requirements without changing every picker. The provider supplies browser defaults, while the resource schema and backend continue to own the upload rules.

Example — One default for attachments, a stricter avatar

The application offers images and PDFs up to 25 MB in its general picker. A profile’s avatar field can still require an image under 2 MB. The narrower field definition takes precedence without a second custom picker.

For engineers

Declare a frontend provider module

Wonder Todos defines its picker as a FrontendAppProviderModule. The capability and protocol identify its role; publicConfig contains browser-visible defaults, not credentials. Imports and the identity comment are omitted.

export const ApplicationFilePickerFrontendAppProvider: FrontendAppProviderModule = {
  metadata: defineProviderMetadata({
    ref: 'wonderTodosFilePicker',
    packageName: '@wonder-todos/main-app',
    tier: ProviderTier.CATALOGUE,
    origin: { kind: ProviderOriginKind.APPLICATION },
  }),
  providerCapabilities: [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_FILE_PICKER],
  protocols: [BUILTIN_PROVIDER_PROTOCOL.FRONTEND_SDK],
  publicConfig: {
    acceptedMimeTypes: ['image/*', 'application/pdf'],
    maxFileSizeMb: 25,
    maxSelectionCount: 10,
    uploadNamespace: 'task-attachments',
  },
};

Make the provider reachable in the application

Export the module through the frontend provider entrypoint, include its contribution in frontend/src/provider-contributions.ts, and declare the same reference under the frontend service’s provider scope in wildo.saas.config.ts. Derive contribution fields from the module so identity and defaults stay aligned.

Framework file fields resolve FRONTEND_FILE_PICKER with FRONTEND_SDK. A custom view should use that registry contract too, rather than maintaining a second table of size and MIME limits.

Let the field override the default

The resolver below shows the precedence directly. Provider megabytes are converted to bytes once; the provider’s selection limit is used only for a multi-file field. Earlier lookup and validation code is omitted.

return {
  allowedMimeTypes: fileMetadata.allowedMimeTypes ?? providerConstraints.acceptedMimeTypes,
  maxSize: fileMetadata.maxSize ?? (
    providerMaxSizeMb === undefined ? undefined : providerMaxSizeMb * 1024 * 1024
  ),
  maxFiles: fileMetadata.multiple
    ? (fileMetadata.maxFiles ?? providerConstraints.maxSelectionCount)
    : fileMetadata.maxFiles,
};

Keep remote selection explicit

A connected provider picker may deliver local File objects or remote references, according to its declared delivery contract. The host checks that declaration before forwarding the selection. A remote reference still needs a matching backend storage provider accepted by the field; a browser picker alone does not make a cloud drive a working storage destination.

Connect the module to the running frontend

Start with wildo compose add-file-picker-provider in the application. Its module is only the first piece: export it through the frontend-provider entrypoint, contribute it to the companion, then select that provider in the frontend service configuration.

Wonder Todos derives the contribution from the module so its advertised capabilities and runtime configuration cannot drift into separate copies:

function buildFilePickerContribution(): ProviderCompanionContribution {
  return {
    ref: ApplicationFilePickerFrontendAppProvider.metadata.ref,
    runtimeImportPath: '@wonder-todos/main-app/frontend-providers',
    runtimeTargets: [{ kind: 'frontendService', serviceType: AppFrontendType.SAAS_APP }],
    engineCapabilities: [],
    providerCapabilities: [...ApplicationFilePickerFrontendAppProvider.providerCapabilities],
    protocols: [...ApplicationFilePickerFrontendAppProvider.protocols],
    secretsContractShape: [],
    frontendEntry: {
      metadata: ApplicationFilePickerFrontendAppProvider.metadata,
      providerCapabilities: [...ApplicationFilePickerFrontendAppProvider.providerCapabilities],
      protocols: [...ApplicationFilePickerFrontendAppProvider.protocols],
      publicConfig: ApplicationFilePickerFrontendAppProvider.publicConfig,
    },
    sourceModuleId: 'tasks-manager',
  };
}

This function belongs in frontend/src/provider-contributions.ts, alongside the application’s contribution list. ProviderCompanionContribution and AppFrontendType come from @wildo-ai/saas-models; the provider is imported from the local provider entrypoint. Include the returned contribution in that list.

SurfaceWhat must agree
Frontend provider entrypointThe package’s ./frontend-providers export reaches the module
Companion contributionruntimeImportPath reaches that export; sourceModuleId identifies the owning module
Service selectionproviders.scopes.frontendServices.app.providers.<ref> selects the same ref, capability and protocol
Field declarationExplicit MIME, size and selection limits take precedence over provider defaults

Configuration sync checks contribution reachability. After sync, verify the provider is selected for the actual frontend service: exporting a module alone does not activate it. Keep credentials out of publicConfig; these values are delivered to the browser.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.