JavaScript Node cloneNode() Method

Beginner
⏱️ 11 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Instance method

What You’ll Learn

The Node.cloneNode() method returns a duplicate of a node. Learn deep vs shallow cloning, what is and is not copied, the duplicate-id warning, and when to prefer document.importNode().

01

Kind

Instance method

02

Returns

New Node copy

03

deep

true = subtree

04

Listeners

Attributes only

05

In document?

Not until append

06

Status

Baseline widely

Introduction

When you need another copy of a DOM node instead of moving the original, cloneNode() is the tool. Pair it with appendChild() to insert the copy.

Cloning copies attributes by default. It does not copy addEventListener handlers or paint data for <canvas>. Always watch for duplicate id values when both nodes stay in the same document.

💡
Beginner tip

Pass true for a deep clone (children included). Omit it or pass false for a shallow clone (element shell only).

Understanding cloneNode()

MDN: cloneNode() returns a duplicate of the node. The optional deep flag controls whether the subtree is copied too.

  • Attributes — copied, including inline event attributes.
  • Subtree — copied only when deep is true.
  • Not copiedaddEventListener / onevent properties; canvas paint.
  • Parent — clone starts detached (parentNode is null).

📝 Syntax

JavaScript
const copy = node.cloneNode();
const deepCopy = node.cloneNode(true);

Parameters

  • deep (optional) — true clones the node and its whole subtree; false or omitted clones only the node itself (no children / nested text).

Return value

A new Node that is a copy of the original. It is not in the document until you append or insert it.

⚖️ cloneNode() vs importNode()

cloneNode()document.importNode()
Document contextDocument that owns the original nodeThe document you call it on
Custom elementsUses the source document’s registryUses the target document’s registry
Template contentCan miss upgrades for custom elementsPreferred for <template> content
Same-document copiesUsual choiceAlso works; often unnecessary

MDN: to clone nodes for another document, or template content with custom elements, use importNode() on the target document.

⚡ Quick Reference

GoalCode
Deep copynode.cloneNode(true)
Shallow copynode.cloneNode(false) or node.cloneNode()
Insert the copyparent.appendChild(node.cloneNode(true));
Avoid duplicate idcopy.id = "card-2";
Other document / templatedocument.importNode(node, true)
MDN statusBaseline Widely available (since July 2015)

🔍 At a Glance

Four facts to remember about Node.cloneNode().

Returns
Node (copy)

Detached clone

Baseline
widely

Since July 2015

deep true
subtree

Children included

Listeners
attrs only

Not addEventListener

Examples Gallery

Examples follow MDN Node.cloneNode() patterns. Use View Output or Try It Yourself for each case.

📚 Getting Started

Deep vs shallow clones and inserting the copy into the page.

Example 1 — Deep Clone (MDN-style)

cloneNode(true) copies the node and its descendants.

JavaScript
const p = document.getElementById("para1");
const p2 = p.cloneNode(true);

console.log(p2.childNodes.length > 0); // true (children copied)
console.log(p2.textContent.trim());    // includes nested text
Try It Yourself

How It Works

With deep === true, nested elements and text nodes are duplicated. The original p is unchanged.

Example 2 — Shallow Clone Omits Children

Default / false copies the element without its subtree.

JavaScript
const card = document.getElementById("card");
const shell = card.cloneNode(false);

console.log(card.children.length);  // e.g. 1
console.log(shell.children.length); // 0
console.log(shell.className);       // attributes still copied
Try It Yourself

How It Works

You get an empty element with the same tag and attributes. Nested content is not included. Void elements are unaffected by deep.

📈 Insert, IDs & Listeners

Put the clone in the tree, fix duplicate ids, and re-attach listeners.

Example 3 — Clone Then Append

The clone is detached until you insert it.

JavaScript
const source = document.getElementById("source");
const list = document.getElementById("list");

const copy = source.cloneNode(true);
console.log(copy.parentNode); // null

list.appendChild(copy);
console.log(list.children.length); // original + copy
Try It Yourself

How It Works

Unlike appendChild(source) (which moves), cloning keeps the original and adds a separate node.

Example 4 — Fix Duplicate id After Cloning

MDN warning: change the clone’s id before inserting it.

JavaScript
const original = document.getElementById("card-1");
const copy = original.cloneNode(true);
copy.id = "card-2";

document.getElementById("host").appendChild(copy);

console.log(document.getElementById("card-1") !== null);
console.log(document.getElementById("card-2") !== null);
console.log(document.querySelectorAll("[id='card-1']").length); // 1
Try It Yourself

How It Works

Assigning a new id before append keeps getElementById predictable. Consider name attributes the same way when duplicates matter.

Example 5 — addEventListener Is Not Cloned

Inline attributes copy; JS-attached listeners do not.

JavaScript
const btn = document.getElementById("btn");
let clicks = 0;
btn.addEventListener("click", function () { clicks++; });

const clone = btn.cloneNode(true);
document.getElementById("host").appendChild(clone);

clone.click();
console.log(clicks); // 0 — listener was not copied

btn.click();
console.log(clicks); // 1 — original still works
Try It Yourself

How It Works

Re-bind handlers on the clone after cloning, or use event delegation on a parent so copies work without re-attaching.

🚀 Common Use Cases

  • Duplicating a card, list item, or row template already in the DOM.
  • Keeping the original in place while inserting a copy elsewhere.
  • Building many similar nodes from one prototype with cloneNode(true).
  • Shallow-cloning a wrapper when you only need the element shell and attributes.
  • Switching to importNode for cross-document or <template> custom elements.

🔧 How It Works

1

Call cloneNode

Pass deep true for subtree, or false/omit for the node only.

Copy
2

Attributes duplicated

Including id and inline event attributes; JS listeners stay behind.

Attrs
3

Adjust the clone

Change id / name, update text, re-bind listeners as needed.

Edit
4

Insert into the DOM

appendChild or insertBefore attaches the detached copy.

📝 Notes

Universal Browser Support

Node.cloneNode() is Baseline Widely available across modern browsers (MDN: since July 2015). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline · Widely available

Node.cloneNode()

Safe for production. Use deep true for full copies; fix ids; re-bind addEventListener handlers.

Universal Widely available
Google Chrome Full support · Desktop & Mobile
Full support
Mozilla Firefox Full support · Desktop & Mobile
Full support
Apple Safari Full support · macOS & iOS
Full support
Microsoft Edge Full support · Chromium & Legacy
Full support
Opera Full support · Modern versions
Full support
Internet Explorer Long-standing support in legacy IE
Full support
cloneNode() Excellent

Bottom line: Deep-clone when you need children; shallow for the shell; importNode for other documents / template custom elements.

Conclusion

Node.cloneNode() duplicates a node. Choose deep or shallow, fix ids, remember listeners are not fully copied, and append the detached clone when you are ready.

Continue with compareDocumentPosition(), appendChild(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Use cloneNode(true) for full UI copies
  • Change id (and name if needed) before insert
  • Re-attach addEventListener handlers on clones
  • Prefer importNode for templates with custom elements
  • Append the clone—it starts detached

❌ Don’t

  • Leave duplicate ids in the same document
  • Assume JS listeners were copied
  • Expect canvas drawings to come along
  • Confuse cloning with moving via appendChild
  • Confuse DOM Node with the Node.js runtime

Key Takeaways

Knowledge Unlocked

Five things to remember about cloneNode()

Duplicate a node; deep controls the subtree.

5
Core concepts
🌳 02

deep true

copies subtree

Flag
🚩 03

Fix ids

avoid duplicates

Gotcha
🔒 04

Listeners

attrs only

Events
📦 05

importNode

other documents

Alt

❓ Frequently Asked Questions

It returns a duplicate of the node. With deep true, the whole subtree is copied; with false or omitted, only the node itself is cloned (no children).
No. MDN marks Node.cloneNode() as Baseline Widely available (since July 2015). It is a standard DOM method — not Deprecated, Experimental, or Non-standard.
It copies attributes, including inline handlers like onclick="...". It does not copy listeners added with addEventListener() or assigned via onevent properties such as node.onclick = fn.
If the original has an id and you insert the clone into the same document, you get two elements with the same id. Change the clone’s id (and sometimes name) to stay unique.
Use document.importNode() when cloning into another document, or when cloning HTML template content that may include custom elements that should upgrade in the current document.
No. The clone has no parent until you insert it with appendChild, insertBefore, or a similar method.
Did you know?

MDN notes that deep has no effect on void elements such as <img> and <input>—they have no children to clone either way.

Next: compareDocumentPosition()

Learn bitmask flags for relative node position in the document.

compareDocumentPosition() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful