Skip to content
Files SDK
Esc
navigateopen⌘Jpreview
On this page

search

Find objects whose key matches a glob (default), regex, substring, or exact pattern - a streaming async iterable that walks every page like listAll.

files.search(pattern, options?)

Find objects whose key matches pattern, walking every page like listAll. It’s a streaming async iterable of StoredFile, so it stays memory-bounded on large buckets and you can break to stop early.

// Glob is the default: `*` stays within a path segment, `?` matches one char.
for await (const file of files.search("avatars/*.png")) {
  console.log(file.key, file.size);
}

// Collect into an array when you want them all at once:
const pdfs = await Array.fromAsync(files.search("invoices/2024/*.pdf"));

Matching is against the caller-facing key, so a client prefix on the instance is already stripped before the pattern is tested.

Glob syntax

"glob" mode uses standard glob semantics, powered by picomatch:

  • * — any run of characters within a path segment (does not cross /).
  • ** — a globstar segment that spans path segments. Write it as its own segment: photos/**/*.jpg matches at any depth, including zero subfolders.
  • ? — a single non-/ character.
  • [a-z], {a,b} — character classes and brace alternation.
  • !pattern — negation (matches everything except).

The pattern is anchored to the whole key, and dotfiles are matched (object keys are opaque, not hidden files). A glob with no wildcards is an exact match, not a substring — files.search("report.pdf") matches the key report.pdf and nothing else. Use match: "substring" for “contains”.

// Every JPEG at any depth under photos/:
for await (const file of files.search("photos/**/*.jpg")) {
  // photos/cover.jpg, photos/2024/spain/beach.jpg, ...
}

Match modes

Pass a match mode to change how a string pattern is interpreted, or pass a RegExp directly (which always matches by regex and ignores match):

// Regular expression (string form):
files.search("\\.(png|jpe?g)$", { match: "regex" });

// ...or a RegExp instance:
files.search(/\.(png|jpe?g)$/);

// Substring — key contains the text anywhere:
files.search("report", { match: "substring" });

// Exact — key equals the text:
files.search("invoices/2024/q1.pdf", { match: "exact" });

// Case-insensitive (any mode):
files.search("*.PNG", { caseInsensitive: true });

An invalid regex pattern throws a FilesError before the walk begins.

Scoping the walk with prefix

search reads every page under a prefix, following the cursor. For a glob, the literal head of the pattern is pushed down automatically as that prefix, so files.search("uploads/2024/*.pdf") scopes the walk to the uploads/2024 prefix rather than the whole bucket.

Other modes carry no inferable prefix, so for a regex, substring, or caseInsensitive search over a large bucket, pass prefix yourself to bound the walk:

// Only walk logs/ — then regex-match within it:
files.search("error|panic", { match: "regex", prefix: "logs/" });

A glob’s auto push-down is disabled when caseInsensitive is set (a provider’s prefix filter is case-sensitive), so combine caseInsensitive with an explicit prefix to scope it.

Stopping early

maxResults caps the number of matches yielded; because the walk is lazy, it also stops paging once the cap is hit. Equivalently, break out of the loop.

// First 10 matches, then stop fetching pages:
const recent = await Array.fromAsync(
  files.search("**/*.log", { maxResults: 10 })
);

Provider support

search runs on every adapter, since it’s built on listAll — there’s no per-provider search capability and nothing to gate. The two listAll caveats carry over: on Netlify Blobs omit limit to walk everything, and the non-recursive Box / OneDrive / SharePoint adapters only see the immediate children of the root folder. An unbounded search with no prefix walks the whole bucket by design.

Options

Could not generate a type table for SearchOptions: Cannot read properties of undefined (reading 'ESNext')

The match mode is one of:

Could not generate a type table for SearchMatch: Cannot read properties of undefined (reading 'ESNext')

Was this page helpful?