The write operation in JavaScript encompasses several distinct concepts: writing to the document using legacy methods, writing to the system clipboard using modern APIs, and writing to streams for data processing. Understanding when and how to use each approach is essential for building modern, performant web applications. Our /services/web-development/ team specializes in implementing these patterns correctly.
Understanding document.write()
The document.write() method is one of JavaScript's oldest methods for adding content to web pages, but its use is strongly discouraged in modern web development. MDN Web Docs explicitly warns that document.write() has "very idiosyncratic behavior" that can affect the HTML parser in unpredictable ways.
When troubleshooting issues with legacy code, check our guide on /resources/docs/web-development/errors/ for common JavaScript error patterns and solutions.
1// Legacy document.write() - AVOID IN MODERN CODE2document.write('<p>Hello, World!</p>');3 4// Multiple parameters5document.write('<h1>Title</h1>', '<p>Paragraph text</p>');6 7// Problem: If called after page load, this clears EVERYTHING8// document.open(); // Automatically called9// document.write('<h1>New Content</h1>');10// document.close(); // Implicit behaviorModern Alternatives to document.write()
For most use cases, manipulating the DOM directly provides better performance and more predictable behavior than document.write(). See our comprehensive guide on /resources/docs/web-development/working-with-objects/ for detailed patterns on DOM manipulation and object handling.
1// Modern DOM manipulation - RECOMMENDED2 3// Using innerHTML to set HTML content4document.getElementById('container').innerHTML = '<p>Hello, World!</p>';5 6// Using textContent for plain text - SAFE from XSS7const userInput = '<script>alert("xss")</script>';8document.getElementById('message').textContent = userInput;9// Output: <p><script>alert("xss")</script></p>10 11// Creating and appending elements12const newParagraph = document.createElement('p');13newParagraph.textContent = 'This is dynamically added content.';14document.body.appendChild(newParagraph);15 16// Using insertAdjacentHTML for efficient insertion17const button = document.getElementById('myButton');18button.insertAdjacentHTML('afterend', '<span>New content after button</span>');Better Performance
No document clearing or re-parsing of existing content
Security
textContent automatically prevents XSS attacks
Control
Precise positioning with appendChild, insertBefore, etc.
Compatibility
Works with XML, XHTML, and HTML documents
Copy to Clipboard Functionality
Modern browsers provide the Clipboard API for programmatic access to the system clipboard. The navigator.clipboard.write() method allows writing arbitrary ClipboardItem data, including text and images, to the clipboard. This is the recommended approach for implementing copy-to-clipboard functionality.
For async data operations, pair clipboard functionality with our guide on /resources/docs/web-development/fetch/ to efficiently retrieve and manipulate data.
1// Modern Clipboard API - Writing Text2 3async function copyTextToClipboard(text) {4 try {5 // Create a ClipboardItem with text/plain type6 const clipboardItem = new ClipboardItem({7 'text/plain': new Blob([text], { type: 'text/plain' })8 });9 10 // Write to clipboard11 await navigator.clipboard.write([clipboardItem]);12 console.log('Text copied to clipboard successfully');13 } catch (error) {14 console.error('Failed to copy text:', error);15 }16}17 18// Simpler alternative for plain text19async function copySimpleText(text) {20 try {21 await navigator.clipboard.writeText(text);22 console.log('Text copied successfully');23 } catch (error) {24 console.error('Failed to copy:', error);25 }26}1// Copy Image to Clipboard2 3async function copyCanvasToClipboard(canvasElement) {4 try {5 // Convert canvas to blob6 const blob = await new Promise((resolve, reject) => {7 canvasElement.toBlob(blob => {8 if (blob) resolve(blob);9 else reject(new Error('Canvas toBlob failed'));10 });11 });12 13 // Create ClipboardItem with image data14 const clipboardItem = new ClipboardItem({15 [blob.type]: blob16 });17 18 // Write to clipboard19 await navigator.clipboard.write([clipboardItem]);20 console.log('Image copied to clipboard');21 } catch (error) {22 console.error('Failed to copy image:', error);23 }24}25 26// Practical example: Copy button27document.getElementById('copyButton').addEventListener('click', async () => {28 await copySimpleText('Text to copy');29 // Show feedback to user30 showToast('Copied to clipboard!');31});Writable Streams in JavaScript
The Streams API provides a powerful interface for writing data to destinations asynchronously, chunk by chunk. Writable streams are particularly useful for handling large data sets, processing data in real-time, or writing to destinations that may not be immediately available.
1// Creating a Writable Stream2 3const writableStream = new WritableStream({4 start(controller) {5 // Called immediately after construction6 console.log('Stream started');7 },8 9 write(chunk, controller) {10 // Called for each chunk of data11 // Returns a Promise that resolves when done12 return new Promise((resolve, reject) => {13 console.log('Processing chunk:', chunk);14 processData(chunk);15 resolve();16 });17 },18 19 close(controller) {20 // Called when no more data is expected21 console.log('Stream closed');22 },23 24 abort(reason) {25 // Called when the stream is aborted26 console.error('Stream aborted:', reason);27 }28}, {29 highWaterMark: 3, // Maximum queue depth30 size: () => 1 // Size of each chunk31});1// Writing to a Writable Stream2 3async function writeToStream(data) {4 const writer = writableStream.getWriter();5 6 try {7 for (const chunk of data) {8 // Wait for the writer to be ready (backpressure)9 await writer.ready;10 11 // Write the chunk12 writer.write(chunk);13 }14 15 // Close the stream when done16 await writer.ready;17 writer.close();18 } catch (error) {19 // Handle errors20 writer.abort(error);21 } finally {22 // Release the writer lock23 writer.releaseLock();24 }25}26 27// Example: Streaming data processing28const data = ['chunk1', 'chunk2', 'chunk3', 'chunk4'];29writeToStream(data);1// Practical Example: File Writing with Stream2 3async function saveDataToFile(data, filename) {4 // Request file access5 const handle = await window.showSaveFilePicker({ suggestedName: filename });6 const writable = await handle.createWritable();7 8 // Create a writable stream with the file as sink9 const stream = new WritableStream({10 write(chunk) {11 return writable.write(chunk);12 },13 close() {14 return writable.close();15 },16 abort(error) {17 return writable.abort(error);18 }19 });20 21 // Write data to the stream22 const writer = stream.getWriter();23 const encoder = new TextEncoder();24 25 for (const item of data) {26 await writer.ready;27 writer.write(encoder.encode(JSON.stringify(item) + '\n'));28 }29 30 await writer.close();31 console.log('File saved successfully');32}Security Best Practices
When working with write operations, security should be a top priority. Here are essential practices for secure JavaScript writing.
1// Trusted Types API for XSS Prevention2 3// Create a trusted types policy4const policy = trustedTypes.createPolicy('myPolicy', {5 createHTML: (string) => {6 // Sanitize the input - use a library like DOMPurify7 return string8 .replace(/</g, '<')9 .replace(/>/g, '>')10 .replace(/"/g, '"')11 .replace(/'/g, ''');12 }13});14 15// Use the policy when writing to DOM16const userInput = '<script>alert("xss")</script>';17element.innerHTML = policy.createHTML(userInput);18// Safe output: <script>alert("xss")</script>1// Secure Clipboard Usage2 3// Always require user activation4document.getElementById('copyButton').addEventListener('click', async () => {5 try {6 // Check if clipboard permission is granted7 const permission = await navigator.permissions.query({ name: 'clipboard-write' });8 9 if (permission.state === 'granted') {10 await navigator.clipboard.writeText(textToCopy);11 showToast('Copied!');12 } else {13 // Request permission14 await navigator.clipboard.writeText(textToCopy);15 showToast('Copied!');16 }17 } catch (error) {18 console.error('Clipboard access denied:', error);19 showToast('Failed to copy');20 }21});Avoid document.write()
Use DOM manipulation methods instead
Sanitize Input
Always sanitize user input before inserting HTML
Use textContent
Prefer textContent over innerHTML for plain text
Trusted Types
Enable Trusted Types API for additional protection
Summary
The concept of "write" in JavaScript has evolved significantly from the early days of document.write(). Modern web development favors explicit DOM manipulation methods like innerHTML, textContent, and createElement() for adding content to pages, as these provide better performance, security, and control.
For clipboard functionality, the modern navigator.clipboard API provides a standardized way to read from and write to the system clipboard, supporting both text and image content with proper security considerations.
For handling large data or streaming scenarios, the Writable Streams API offers a sophisticated approach to writing data asynchronously with built-in backpressure management.
Understanding when to use each of these approaches--and when to avoid legacy methods like document.write()--is fundamental to building modern, performant, and secure web applications. Our /services/web-development/ team can help you implement these patterns correctly.
Frequently Asked Questions
Sources
- MDN Web Docs: Document.write() - Official documentation with syntax, parameters, security considerations, and code examples
- MDN Web Docs: Clipboard.write() - Modern clipboard API for writing text and images
- MDN Web Docs: Using writable streams - Streams API writable stream implementation guide
- Stack Overflow: What are alternatives to document.write? - Community discussion explaining why document.write() is problematic
- Chrome Developer Blog: Intervening against document.write() - Browser intervention behavior details