//native
/**
* Duplicate Page
* Copy a page's title, icon, cover and content into a new page under a parent page, via Notion-flavored Markdown. Database properties, comments and child pages' own content are not copied; uploaded-file icons and covers are skipped.
*/
export async function main(
auth: RT.Notion,
page_id: string,
parent_page_id: string,
title: string | undefined
) {
const headers = {
Authorization: `Bearer ${auth.token}`,
Accept: "application/json",
"Notion-Version": "2026-03-11",
}
const get = async (path: string) => {
const response = await fetch(`https://api.notion.com/v1/${path}`, {
headers,
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
return await response.json()
}
const page = await get(`pages/${page_id}`)
const content = await get(`pages/${page_id}/markdown`)
if (content.truncated) {
throw new Error(
"Page is too large to copy in one request (truncated markdown)"
)
}
const source = Object.values(page.properties).find(
(p: any) => p.type === "title"
) as { title: { plain_text: string }[] }
const keep = (v: any) =>
v && v.type !== "file" && v.type !== "file_upload" ? v : undefined
const body: { [key: string]: any } = {
parent: { type: "page_id", page_id: parent_page_id },
properties: {
title: {
title: [
{
text: {
content: title || source.title.map((t) => t.plain_text).join(""),
},
},
],
},
},
icon: keep(page.icon),
cover: keep(page.cover),
}
if (content.markdown) body.markdown = content.markdown
const response = await fetch("https://api.notion.com/v1/pages", {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify(body),
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
return await response.json()
}
Submitted by hugo989 4 hours ago