Forge equivalent for detecting draft status on a Confluence Page

Hello community,

I’m migrating a Connect app to Forge and need help finding the equivalent way to detect if a Confluence page is in draft status.

In Connect, I used the following approach:

AP.navigator.getLocation(function(location) {
    var draftStatus;
    if (location && location.context && location.context.contentId) {
        id = location.context.contentId;
        draftStatus = (location.target === "contentcreate");
    }
});

This draftStatus variable was then passed to my backend REST API calls to handle draft vs. published pages differently:

function doGetDumpFromAttachment(id, jwt, callback) {
    var url = serverURL + "/confluence/fetch?attachmentID=" + id 
        + "&draftStatus=" + draftStatus 
        + "&platformToken=" + jwt;
    // ... rest of the logic
}

My Question: What is the equivalent way in Forge to:

  1. Detect if the current page context is a draft (being created/edited) vs. a published page?

  2. Access this information to pass to Confluence REST API calls?

Any guidance on the Forge approach would be greatly appreciated!

Hey @AndreaSerra,

All modules in Forge should receive a location property within their context which references the url which they are being rendered in. This operates similar to the getLocation method in Connect and should contain similar information related to whether a page is in draft.

Thank you for the response!

I can confirm that I’m receiving the context.extension object in Forge, but the structure is quite different from Connect’s AP.navigator.getLocation().

In Connect, the location object provided structured data:

{
    target: "contentcreate",  // explicit indicator for draft status
    context: {
        contentId: "123456"
    }
}

In Forge, I’m receiving:

{
    "type": "macro",
    "content": {
        "id": "429883393",
        "type": "page",
        "title": "Confluence Page"
    },
    "isEditing": true,
    "location": "https://[domain]/wiki/spaces/[space]/pages/edit-v2/429883393?draftShareId=82ca23aa-6aa4-4d7b-9237-985b59471c88"
}

My questions:

  1. The isEditing property doesn’t distinguish between draft and published pages - it’s true when editing any page, whether it’s a draft or an already-published page being edited. How should I detect specifically if the page is in draft status (never published yet)?

  2. Should I rely on URL parsing? I notice the draftShareId query parameter appears in the location URL for drafts. Would checking for this parameter be the recommended approach?

const isDraft = context.extension.location.includes('draftShareId=');
  1. What about API stability? If I need to rely on URL patterns (like the presence of draftShareId or the edit-v2 path segment), are these considered stable parts of the API, or could they change in future Confluence updates? I want to ensure my app doesn’t break unexpectedly.

It would be helpful to understand the recommended best practice for reliably detecting draft vs. published page status in Forge, especially for long-term maintenance.

Thanks again for your help!

1 Like

How does your app behave on a Live Doc where there is no draft vs published distinction? Configure live docs in Confluence | Confluence Cloud | Atlassian Support

In Live Docs, our app behaves as if it’s in edit mode on a classic page (since Live Docs don’t have the draft/published distinction). This works fine for our use case.

I’m not sure I understand how this relates to my original question about detecting draft status in classic Confluence pages.

My concern is specifically about classic pages where there IS a draft vs. published distinction:

  • Draft pages (being created for the first time, never published)

  • Published pages (already published, can be viewed by users)

  • Published pages being edited (already published, currently being modified)

In Connect, location.target === "contentcreate" explicitly told us when a page was in draft status (first scenario). This was important because our app needs to handle these three scenarios differently when making REST API calls.

Looking at the Confluence REST API v2 documentation for pages and blog posts, I can see both endpoints return a status field that indicates whether the content is “current” (published) or “draft”.

Since I have the content ID from context.extension.content.id and the type from context.extension.content.type, I could make an API call to fetch the status:

// Get content ID and type from context
const contentId = context.extension.content.id;
const contentType = context.extension.content.type; // "page" or "blogpost"

// Call appropriate API endpoint to get status
const endpoint = contentType === "page" 
    ? `/wiki/api/v2/pages/${contentId}` 
    : `/wiki/api/v2/blogposts/${contentId}`;

// Response will include: { "status": "draft" } or { "status": "current" }

Is this the recommended approach in Forge to detect draft vs. published status for classic pages, or is there a more direct way without making an additional API call?

This would be more reliable than parsing URL parameters like draftShareId, but I want to confirm this is the intended pattern before implementing it.