Skip to main content

Upload File

Uploads a browser file to cloud storage when triggered, reporting progress and yielding a cloudfile handle.

Upload File takes a browser File (typically from Open File Picker) on its untyped file input and, when upload fires, stores it in the cloud backend's file storage. Progress streams out (progressLoadedPercent, byte counts, progressChanged), and on done the stored file is available as cloudFile — the handle to attach to a record's file property or unwrap with Cloud File. failure carries error and errorStatus.

When to use it

Attachments, avatars, imports — any user-picked file that must persist server-side. The upload stores the file only; associating it with a record is a separate write (Create/Set Record).

At a glance

CategoryCloud Services
Type nameUpload File
Available inbrowser
SSR compatibilitysafe
Provided bynoodl-viewer-react

Inputs

Values

NameTypeDefaultDescription
bucketStringSupabase Storage bucket to upload into. Supabase only; there is no default, and a bucket that does not exist fails with an error that does not say so
collectionStringPocketBase collection holding the record the file attaches to. PocketBase only
fieldStringThe file-typed field on that record. PocketBase only
file*The file to upload, as an Open File Picker node produces it
pathStringObject path inside the bucket, such as avatars/me.png. Supabase only. Leave blank to use the file's own name
privateBooleanfalseRestricts the stored file to whoever uploaded it, so reading it later needs a Sign File URL node
recordIdStringExisting record to attach the file to. PocketBase only. Leave blank to create a new record as part of the upload

Signals

NameTypeDefaultDescription
uploadSignalStarts uploading File, and fails straight away when no file has been set

Outputs

Values

NameTypeDefaultDescription
cloudFileCloudfileThe stored file, for wiring into a record property or a Cloud File node
progressLoadedBytesNumberHow much of the file has been sent so far, in bytes
progressLoadedPercentNumberHow much of the file has been sent so far, from 0 to 100
progressTotalBytesNumberSize of the file being uploaded, in bytes

Signals

NameTypeDefaultDescription
completedSignalFires after every invocation, whatever the outcome — wire this to carry on regardless. Failure still fires and still carries its reason, so this cannot hide an error
doneSignalFires once the file is stored and Cloud File is up to date
progressChangedSignalFires each time the byte counts below move during an upload

Failure outputs

NameTypeDefaultDescription
errorStringWhy the last upload failed; empty until one does
errorStatusNumberHTTP status the backend refused with, or 0 when the request never left the app
failureSignalFires when the file could not be stored, after the reason has been reported on the error channel

Dynamic ports

This node's port list changes at runtime (runtime-discovered); the tables above may be incomplete for a given instance.

Some ports are discovered at runtime from user code, parameters or connected components, and are pushed to the editor per instance; the static port list below is incomplete for such instances.

Ports at runtime

A backendId (Backend) input is registered at runtime rather than declared, so it appears only once a project has more than one backend — the node then uploads through whichever backend the picker names instead of the project's cloudservices endpoint (BCN-007 step 6). A backend id naming nothing is an error, never a silent fallback. The static inputs are also per backend, not universal: bucket and path are Supabase Storage only, and collection/recordId/field are PocketBase only, because PocketBase stores a file as a field on a record rather than as an object of its own. Leave them unset on the built-in, Parse and Directus backends. BCN-010 gates the node on files.upload, so a backend that cannot accept an upload marks the node with the reason before it is triggered.

Patterns

  • Picker doneupload, upload done → record write: three nodes, each owning one step.
  • private: true uploads pair with Sign File URL: wire the same done signal to both the record write and the signer.

Watch out for

  • Treating cloudFile as set before done fired — sequence record writes on the Done signal.
  • Setting private: true and then binding cloudFile.url straight to an Image/link — a private file's plain url 403s for anyone but the uploader; sign it first.

Examples

Create a record with an uploaded file attachment

The create-with-attachment flow: Open File Picker hands the picked browser file to Upload File, which stores it in cloud storage and outputs a cloudFile. Cloud File exposes that file's url, previewed in an Image (the cloudfile→image cast). When the upload succeeds, Create Record (NewDbModelProperties) writes a new 'Attachment' record whose properties — including the file — are set on the node's schema-generated inputs.

Upload a private file and preview it with a signed URL

Open File Picker hands the picked file to Upload File with its private input set, so the backend ACLs the upload to its uploader instead of leaving it public. A private file's plain URL is not directly usable in an <img> — it 403s for anyone else, including an unauthenticated preview — so on the picker's done the resulting cloudFile is wired into Sign File URL, whose sign signal is fired from the same done. Sign File URL mints a short-TTL signed URL (the row-ACL check that gates it is the same one the file's own GET route uses), and THAT url — not the cloudFile's own plain url — feeds the Image's src. Re-signing before every render (rather than persisting the signed URL) is the idiomatic use: a stored, expired signature just 403s later.

Open File Picker, Cloud File, Sign File URL, Create Record, Update Record

Generated

This page is generated from node-catalog-enriched.json. Do not edit it by hand — run npm run docs:nodes to regenerate, and fix the source enrichment instead.