Skip to content

Confluence — Search (CQL)

import { ForgeFunctionAdapter, asApp } from '@forge-clients/core';
const adapter = new ForgeFunctionAdapter({ product: 'confluence' });
import { search } from '@forge-clients/confluence/v1';
const results = await search(asApp(adapter), {
cql: 'space = "MYSPACE" AND type = page ORDER BY lastModified DESC',
limit: 25,
expand: ['version', 'space'],
});
console.log(`Found ${results.totalSize} results`);
for (const item of results.results ?? []) {
console.log(item.content?.title);
}
const textResults = await search(asApp(adapter), {
cql: 'text ~ "deployment guide" AND type = page AND space.type = global',
limit: 10,
});
const recent = await search(asApp(adapter), {
cql: 'lastModified >= "2024-01-01" AND type in (page, blogpost) ORDER BY lastModified DESC',
limit: 50,
expand: ['version'],
});

The search endpoint returns cursor-based pagination via _links.next. Use iterateCursorPages to iterate through all results without loading them all into memory:

import { iterateCursorPages } from '@forge-clients/core';
import { search } from '@forge-clients/confluence/v1';
const appClient = asApp(adapter);
// iterateCursorPages yields individual search result items
for await (const result of iterateCursorPages(
(cursor) => search(appClient, {
cql: 'space = "MYSPACE" AND type = page ORDER BY lastModified DESC',
limit: 25,
cursor,
}),
)) {
// result is a SearchResult — fully typed
console.log(result.content?.title);
console.log(result.url);
}

For smaller result sets where you want everything in one array, collect them manually:

const allResults: SearchResult[] = [];
for await (const result of iterateCursorPages(
(cursor) => search(appClient, { cql: 'space = "MYSPACE"', limit: 50, cursor }),
)) {
allResults.push(result);
}