Skip to main content

Storage picker

Embedded apps can open a file or folder picker in a Shellui modal. The user browses storage, keeps a selection while navigating, then confirms. The SDK returns serializable items — your app renders them however it wants.

The picker UI lives in the files app (storage.filesUrl). The root shell opens it in a dedicated modal so it can stack above Settings.

Setup

Set storage.url and storage.filesUrl in shellui.config.ts:

storage: {
url: 'http://localhost:8001',
filesUrl: 'http://localhost:5175/',
},

The user must be signed in.

Pick folders

Folders only — files are hidden. Pass { multiple: true } to allow more than one.

import { shellui } from '@shellui/sdk';

await shellui.init();

const result = await shellui.selectFolders({ multiple: true });
if (!result) {
// User cancelled
return;
}

for (const folder of result.items) {
console.log(folder.name, folder.path, folder.id);
}

Pick files (and optionally folders)

// Files only (folders are for navigation)
const files = await shellui.selectFiles({ multiple: true });

// Files and folders
const items = await shellui.selectFiles({ multiple: true, folders: true });

What you get back

Each item looks like this:

{
id: string; // Stable id (survives rename)
bucket: string;
path: string; // Location at the time of selection
name: string;
type: 'file' | 'folder';
}

Keep id in your own data. After a folder or file is renamed, resolve the current path:

const { data, error } = await shellui.storage.get(savedId);
if (data) {
// data.path is the current location
}

selectFolders / selectFiles resolve to null when the user closes or cancels the modal. They throw if storage.filesUrl is missing.

Messages

Apps do not need to post these themselves — the SDK methods above do.

TypeDirectionPayload
SHELLUI_SELECT_STORAGEapp → root{ id, multiple, mode: 'folders' | 'files' | 'any' }
SHELLUI_SELECT_STORAGE_RESULTroot → app{ id, items? } or { id, cancelled: true }

Try it

Settings → Advanced → enable developer features → Develop. The storage picker buttons open the same APIs and list selected names with a remove control.