File Storage
Docs menu

Integration guide

Environment variables, editable defaults, mount() options, and backend contracts so you can embed File Storage in your app.

1. Architecture (where secrets live)

Layer Role Credentials
Browser / SDK UI, fetch to your APIs Never embed AWS keys. Public URLs + optional Bearer headers only.
Vite demo client Local demo Only DEMO_* (see vite envPrefix).
example-server / your API S3 ListObjects, PutObject, … AWS_ACCESS_KEY_ID, secret, IAM role, etc.

2. Install, dev, and production build

cd "/path/to/File Manager"
yarn
yarn dev          # S3 proxy (3847) + Vite UI (3000)
yarn build        # dist/file-storage.min.js + .css
Command Purpose
yarn dev Proxy + UI using root .env
yarn build IIFE, ESM, and CSS under dist/
yarn marketing:dev This site on port 3001

Copy env.example → .env in the project root before running the S3 demo.

3. Vite demo: DEMO_*

Only DEMO_* keys are exposed to the browser bundle.

S3 via reference proxy (local)

DEMO_STORE=s3
DEMO_S3_PROXY_BASE_URL=http://localhost:3847
DEMO_S3_PUBLIC_BASE_URL=https://your-bucket.s3.us-east-2.amazonaws.com

HTTP REST API

DEMO_STORE=http
DEMO_HTTP_API_BASE_URL=https://api.example.com

Mock (no network)

DEMO_STORE=mock
Variable Description
DEMO_STORE mock | http | s3
DEMO_S3_PROXY_BASE_URL Origin of S3 proxy (POST /list, /upload, …)
DEMO_S3_PUBLIC_BASE_URL Public HTTPS origin for object URLs
DEMO_APP_AWS_UPLOAD_URL Optional full URL for multipart upload to your app
DEMO_FM_MAX_CONCURRENT_FETCHES Max parallel fetches from UI (default 30)

4. Example S3 proxy: server env

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-2
AWS_BUCKET=
REKOGNITION_REGION=us-east-2
S3_ROOT_PREFIX=
S3_PUBLIC_BASE_URL=
PORT=3847

5. editableOptions

File: src/config/editableOptions.ts. Brand mark, demo URL fallbacks, color mode, logos, subscription tier, flat page size, recents limit, virtual trash folder, and more. Restart Vite after changes.

6. Embedding: FileStorageSDK.mount()

HTML (IIFE)

<link rel="stylesheet" href="https://cdn.example.com/file-storage.css" />
<div id="fm" style="height: 70vh"></div>
<script src="https://cdn.example.com/file-storage.min.js"></script>
<script>
  FileStorageSDK.mount({
    el: '#fm',
    apiKey: 'fs_live_…',
    s3: {
      proxyBaseUrl: 'https://api.example.com/file-manager/s3',
      publicObjectBaseUrl: 'https://bucket.s3.us-east-2.amazonaws.com',
      headers: () => ({
        Authorization: 'Bearer ' + (localStorage.getItem('token') || ''),
      }),
      connection: {
        bucket: 'my-bucket',
        region: 'us-east-2',
        rootPrefix: 'uploads/app/',
      },
    },
  })
</script>

HTTP store

FileStorageSDK.mount({
  el: '#fm',
  apiKey: 'fs_live_…',
  http: {
    baseUrl: 'https://api.example.com',
    headers: () => ({ Authorization: 'Bearer ' + token }),
    endpoints: {
      list: '/api/files/list',
      upload: '/api/files/upload',
    },
  },
})

Custom FileStore

FileStorageSDK.mount({
  el: '#fm',
  apiKey: 'fs_live_…',
  store: myCustomStore, // implements FileStore
})

Returns { unmount: () => void }. Pass rekognitionApi: null to disable image recognition wiring when using s3.

7. HTTP backend contract

Default paths relative to baseUrl:

Path Body
POST /api/files/list { "path": "/" } → { "items": FileEntry[] }
POST /api/files/folder { "parentPath", "name" }
POST /api/files/upload multipart: path, files[]
POST /api/files/rename { "path", "newName" }
POST /api/files/move { "path", "destinationFolderPath" }
POST /api/files/remove { "path" }
POST /api/files/search { "query" } → items
POST /api/files/listByType (optional) { "type", "limit?", "cursor?" } → items + nextCursor
{
  path: string
  name: string
  kind: 'file' | 'folder'
  mime?: string
  size?: number
  updatedAt: number   // epoch ms
  createdAt?: number
  url?: string        // preview URL
}

8. S3 proxy contract

JSON routes relative to proxyBaseUrl (no /api/files prefix by default):

Path Purpose
POST /listList folder
POST /listByTypePaginated type filter
POST /folderCreate folder
POST /uploadMultipart upload
POST /rename / /move / /removeMutations
POST /searchSearch

Optional body field connection: { bucket?, region?, rootPrefix? }. Multipart upload fields: parentPath, files, optional bucket/region/rootPrefix.

9. Uploads via your app (appAwsUploadUrl)

When set on s3, uploads POST multipart to that full URL; all other operations still use proxyBaseUrl. Use this for auth, validation, virus scan, or metadata before writing to S3. Your endpoint should accept the same multipart shape and write keys compatible with list + publicObjectBaseUrl.

10. Framework snippets

Vue 3

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue'
const host = ref<HTMLElement | null>(null)
let unmount: (() => void) | undefined
onMounted(() => {
  if (!host.value) return
  unmount = window.FileStorageSDK.mount({
    el: host.value,
    apiKey: import.meta.env.VITE_FILESTORAGE_API_KEY,
    s3: { proxyBaseUrl: import.meta.env.VITE_FM_PROXY_URL },
  }).unmount
})
onBeforeUnmount(() => unmount?.())
</script>
<template>
  <div ref="host" class="h-[70vh]" />
</template>

React

useEffect(() => {
  const el = ref.current
  if (!el || !window.FileStorageSDK) return
  const { unmount } = window.FileStorageSDK.mount({
    el,
    apiKey: process.env.NEXT_PUBLIC_FILESTORAGE_API_KEY!,
    s3: { proxyBaseUrl: process.env.NEXT_PUBLIC_FM_PROXY_URL! },
  })
  return unmount
}, [])

Angular

Call FileStorageSDK.mount({ el: this.host.nativeElement, … }) in ngAfterViewInit and unmount() in ngOnDestroy.

11. CORS, authentication, and troubleshooting

  • CORS: Allow your file-manager origin on the proxy and app upload APIs (POST, Content-Type / multipart headers).
  • Auth: Pass headers: () => ({ Authorization: 'Bearer …' }) on http or s3.
  • 404 on /listByType: Implement the route or restart the example proxy; the SDK falls back to folder walking.
  • Images without URLs: Set publicObjectBaseUrl (and optional connection.rootPrefix) so the client can build preview URLs.