Based on http://html5-demos.appspot.com/static/a.download.html: (archived)

var fileContent = "My epic novel that I don't want to lose.";
var bb = new Blob([fileContent ], { type: 'text/plain' });
var a = document.createElement('a');
a.download = 'download.txt';
a.href = window.URL.createObjectURL(bb);
a.click();

Modified the original fiddle: http://jsfiddle.net/9av2mfjx/

Answer from Stanislav on Stack Overflow
🌐
4umi
4umi.com › web › javascript › filewrite.php
Writing to the local file system - 4umi useful Javascript
Enter the text to be saved, and optionally a name. Then click the ‘Save’ button to save the text to a local file on your system.
Discussions

html - How to save string from input to existing text JAVASCRIPT - Stack Overflow
I have html page, on that page I have input and button I want to save the string in input into existing file like 'text.txt` this is my html code More on stackoverflow.com
🌐 stackoverflow.com
javascript - save restore local storage to a local file - Stack Overflow
Is there a way to easily save and restore the local storage to a file in jquery or JavaScript? There are 3 scenarios for this: testing with a specific local storage making a backup of the local s... More on stackoverflow.com
🌐 stackoverflow.com
javascript - Save data to local storage - Stack Overflow
W3C Schools gives you detailed ... html and local storage. ... Save this answer. ... Show activity on this post. ... Also this will get you the entire DOM element. I assume you want what's inside the tag so i would say use ... instead. Just referencing the DOM element will give you a circular strucure error when you attempt to stringify ... More on stackoverflow.com
🌐 stackoverflow.com
javascript - How to store files in local storage - Stack Overflow
I am building an online code editor. Currently, I am storing the source file and input file on my server. Is there any way to store the source files on the client-side? I am using UUID to generate a More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 11
289

You can create files in browser using Blob and URL.createObjectURL. All recent browsers support this.

You can not directly save the file you create, since that would cause massive security problems, but you can provide it as a download link for the user. You can suggest a file name via the download attribute of the link, in browsers that support the download attribute. As with any other download, the user downloading the file will have the final say on the file name though.

var textFile = null,
  makeTextFile = function (text) {
    var data = new Blob([text], {type: 'text/plain'});

    // If we are replacing a previously generated file we need to
    // manually revoke the object URL to avoid memory leaks.
    if (textFile !== null) {
      window.URL.revokeObjectURL(textFile);
    }

    textFile = window.URL.createObjectURL(data);

    // returns a URL you can use as a href
    return textFile;
  };

Here's an example that uses this technique to save arbitrary text from a textarea.

If you want to immediately initiate the download instead of requiring the user to click on a link, you can use mouse events to simulate a mouse click on the link as Lifecube's answer did. I've created an updated example that uses this technique.

  var create = document.getElementById('create'),
    textbox = document.getElementById('textbox');

  create.addEventListener('click', function () {
    var link = document.createElement('a');
    link.setAttribute('download', 'info.txt');
    link.href = makeTextFile(textbox.value);
    document.body.appendChild(link);

    // wait for the link to be added to the document
    window.requestAnimationFrame(function () {
      var event = new MouseEvent('click');
      link.dispatchEvent(event);
      document.body.removeChild(link);
    });

  }, false);
2 of 11
113

Some suggestions for this -

  1. If you are trying to write a file on client machine, You can't do this in any cross-browser way. IE does have methods to enable "trusted" applications to use ActiveX objects to read/write file.
  2. If you are trying to save it on your server then simply pass on the text data to your server and execute the file writing code using some server side language.
  3. To store some information on the client side that is considerably small, you can go for cookies.
  4. Using the HTML5 API for Local Storage.
Top answer
1 of 1
2

You can't just access the Filesystem from your browser. Your options depend on what you are trying to achieve.

1. Save a txt file on the users local filesystem

You can create a "downloadable" element directly from JS. Depending on the browser the user will be prompted to allow downloads and/or where to store the file. You cannot access the file afterwards.

function download(filename, text) {
  var element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}

// Start file download.
download("hello.txt","This is the content of my file :)");

Source: https://www.codegrepper.com/code-examples/javascript/javascript+download+text+as+txt+file

2. Save data inside the browser so you can read/write whenever the users visits your website

The localstorage API can create small keyed objects (like 5-10 mb) on the user system. You can read/write anything to or from it that is serializable.

localStorage.setItem('myCat', 'Tom');
const cat = localStorage.getItem('myCat');
localStorage.removeItem('myCat');

Here: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

3. Save a file/data on your server

If you need the file on the server itself, you must create a backend with php, nodejs etc. Then you must implement an endpoint that accepts the data you want to save and inside nodejs you can import the "fs" and directly write files to it.

const fs = require('fs')

const content = 'Some content!'

fs.writeFile('/Users/joe/test.txt', content, err => {
  if (err) {
    console.error(err)
    return
  }
  //file written successfully
})

Source: https://nodejs.dev/learn/writing-files-with-nodejs

Top answer
1 of 4
27

I probably would have just tacked this on as a comment to Nathaniel Johnson's answer, but I don't have the reputation yet! With regard with those methods, here are some more simple versions of his functions:

function getLocalStorage() {
    return JSON.stringify(localStorage)
}

function writeLocalStorage(data) {
    Object.keys(data).forEach(function(key) { localStorage.setItem(key, data[key])})
}
2 of 4
9

The process for saving and retrieving local storage has two parts.

First you must be able to retrieve the contents of local storage in a form that is manageable in javascript. Since local storage is a map of key-value pairs the easiest way to this is to turn local storage into a javascript object. Then take this object and turn it into a JSON string. What you do with this string is up to you but I find it easiest to just have the user copy the string into an email.

function getLocalStorage() {
    var a = {};
    for (var i = 0; i < localStorage.length; i++) {
        var k = localStorage.key(i);
        var v = localStorage.getItem(k);
        a[k] = v;
    }
    var s = JSON.stringify(a);
    return s;
}

When I get the string, I use the following function to turn my local storage into a copy of their local storage. Remember to wipe your local storage clean before duplicating their data with a call to localStorage.clear()

function writeLocalStorage(data) {
    var o = JSON.parse(data);
    for (var property in o) {
        if (o.hasOwnProperty(property)) {
            localStorage.setItem(property, o[property]);
        }
    }
}

The last part of your question is how to protect the data from overwriting. You can't write to a local file, however, you can have copy the data into <textarea> and tell the user how to copy and paste the data into a email or a more direct approach.

🌐
GeeksforGeeks
geeksforgeeks.org › javascript › how-to-save-data-in-local-storage-in-javascript
How to Save Data in Local Storage in JavaScript? - GeeksforGeeks
October 14, 2024 - We will use the localStorage object in JavaScript to save user input data locally in the browser.
Top answer
1 of 5
29

You can use localStorage like this:

// Retrieve your data from locaStorage
var saveData = JSON.parse(localStorage.saveData || null) || {};

// Store your data.
function saveStuff(obj) {
  saveData.obj = obj;
  // saveData.foo = foo;
  saveData.time = new Date().getTime();
  localStorage.saveData = JSON.stringify(saveData);
}

// Do something with your data.
function loadStuff() {
  return saveData.obj || "default";
}

Update 2022:
Since people still view this here's a more modern version. I like to wrap things like this in a service which gives you more control and type safety. You can easily add things like validation and errorhandling.

class LocalStorageService {
  #keys = {
    persons: 'persons',
  };

  constructor() {
    this.storage = window.localStorage;
  }

  addPerson(person) {
    const persons = this.getPersons();
    persons.push(person);
    this.setPersons(persons);
  }

  getPersons() {
    return JSON.parse(this.storage.getItem(this.#keys.persons)) || [];
  }

  getPerson(id) {
    const persons = this.getPersons();
    return persons.find((person) => person.id === id);
  }

  setPersons(persons) {
    this.storage.setItem(this.#keys.persons, JSON.stringify(persons));
  }

  removePerson(person) {
    const persons = this.getPersons();
    const index = persons.indexOf(person);
    persons.splice(index, 1);
    this.setPersons(persons);
  }

  clear() {
    this.storage.clear();
  }
}

const storageService = new LocalStorageService();
const person = {
  id: '1',
  name: 'John',
  age: '20',
};

storageService.addPerson(person);

const persons = storageService.getPersons();
console.log(persons);
Run code snippetEdit code snippet Hide Results Copy to answer Expand

Web Storage API - MDN

2 of 5
7

First, you should use console instead of alert.

And, if you want to use the retrieved object somewhere, you'd better store it in a variable:

var testObject = { 'one': 1, 'two': 2, 'three': 3 };
localStorage.setItem('testObject', JSON.stringify(testObject));
var retrievedObject = JSON.parse(localStorage.getItem('testObject'));
console.log('retrievedObject: ', retrievedObject);
Find elsewhere
🌐
TutorialsPoint
tutorialspoint.com › how-to-create-and-save-text-file-in-javascript
How to Create and Save text file in JavaScript?
October 31, 2023 - <html> <body> <h2>Create a text file and save it to local computer using JavaScript</h2> <p>Enter the file content:</p> <textarea placeholder="Enter your text here..."></textarea> <br/><br/> <button onclick="downloadFile()">Save File</button> <script> const downloadFile = () => { const link = document.createElement("a"); const content = document.querySelector("textarea").value; if (!content.trim()) { alert("Please enter some content!"); return; } const file = new Blob([content], { type: 'text/plain' }); link.href = URL.createObjectURL(file); link.download = "sample.txt"; link.click(); URL.revokeObjectURL(link.href); }; </script> </body> </html>
🌐
DEV Community
dev.to › ukaypromise › how-to-save-to-local-storage-4438
How to save to Local storage - DEV Community
December 31, 2022 - You can use the JSON.stringify method to serialize an object, and the JSON.parse method to deserialize a string back into an object. For example, to store an array in local storage, you could do the following:
🌐
Robkendal
robkendal.co.uk › blog › 2020-04-17-saving-text-to-client-side-file-using-vanilla-js
Saving text to a client-side file using vanilla JS - Rob Kendal
April 17, 2020 - Sure, there are lots of means available to save something to the local machine of a user, but they tend to involve either less-than-ideal solutions such as a browser's local storage, a cookie, or even using the HTML canvas blob .
🌐
Stack Overflow
stackoverflow.com › questions › 69106366 › how-to-store-files-in-local-storage
javascript - How to store files in local storage - Stack Overflow
If you want to avoid saving files in the server, then you can use localStorage/sessionStorage to persist data accross sessions at the client level. Then in your case, you'll have a button to "download" the code directory. ... Some browsers allow filesystem access using the File System Access API. 2022-02-20T00:39:39.96Z+00:00 ... Save this answer.
🌐
Jotform
jotform.com › blog › advice › html5: filesystem api - create files and store them locally using javascript and webkit
HTML5: FileSystem API - Create Files and Store Them Locally Using JavaScript and Webkit | Jotform Blog
April 3, 2023 - The FileSystem-API allows the creation of files and folders as well as their local storage using JavaScript. Files can be simple text files, but even more complex files such as images are possible. Modern Webkit browsers with HTML5 support are already able to handle the FileSystem-API. We show you how you can benefit from the new possibilities. ... To be able to save files and folders from inside the web browser to the local hard drive you’ll need access to the filesystem.
Top answer
1 of 13
31

You can just use the Blob function:

function save() {
  var htmlContent = ["your-content-here"];
  var bl = new Blob(htmlContent, {type: "text/html"});
  var a = document.createElement("a");
  a.href = URL.createObjectURL(bl);
  a.download = "your-download-name-here.html";
  a.hidden = true;
  document.body.appendChild(a);
  a.innerHTML = "something random - nobody will see this, it doesn't matter what you put here";
  a.click();
}

and your file will save.

2 of 13
9

Chromium's File System Access API (introduced in 2019)

There's a relatively new, non-standard File System Access API (not to be confused with the earlier File and Directory Entries API or the File System API). It looks like it was introduced in 2019/2020 in Chromium/Chrome, and doesn't have support in Firefox or Safari.

When using this API, a locally opened page can open/save other local files and use the files' data in the page. It does require initial permission to save, but while the user is on the page, subsequent saves of specific files do so 'silently'. A user can also grant permission to a specific directory, in which subsequent reads and writes to that directory don't require approval. Approval is needed again after the user closes all the tabs to the web page and reopens the page.

You can read more about this newish API at https://web.dev/file-system-access/. It's meant to be used to make more powerful web applications.

A few things to note about it:

  • By default, it requires a secure context to run. Running it on https, localhost, or through file:// should work.

  • You can get a file handle from dragging and dropping a file by using DataTransferItem.getAsFileSystemHandle

  • Initially reading or saving a file requires user approval and can only be initiated via a user interaction. After that, subsequent reads and saves don't need approval, until the site is opened again.

  • Handles to files can be saved in the page (so if you were editing local file '/path/to/file.txt', and reload the page, it would be able to have a reference to the file). They can't seemingly be stringified, so are stored through something like IndexedDB (see this answer for more info). Using stored handles to read/write requires user interaction and user approval.

Here are some simple examples. They don't seem to run in a cross-domain iframe, so you probably need to save them as an html file and open them up in Chrome/Chromium.

Opening and Saving, with Drag and Drop (no external libraries):

<body>
<div><button id="open">Open</button><button id="save">Save</button></div>
<textarea id="editor" rows=10 cols=40></textarea>
<script>
let openButton = document.getElementById('open');
let saveButton = document.getElementById('save');
let editor = document.getElementById('editor');
let fileHandle;
async function openFile() {
  try {
    [fileHandle] = await window.showOpenFilePicker();
    await restoreFromFile(fileHandle);
  } catch (e) {
    // might be user canceled
  }
}
async function restoreFromFile() {
  let file = await fileHandle.getFile();
  let text = await file.text();
  editor.value = text;
}
async function saveFile() {
  var saveValue = editor.value;
  if (!fileHandle) {
    try {
      fileHandle = await window.showSaveFilePicker();
    } catch (e) {
      // might be user canceled
    }
  }
  if (!fileHandle || !await verifyPermissions(fileHandle)) {
    return;
  }
  let writableStream = await fileHandle.createWritable();
  await writableStream.write(saveValue);
  await writableStream.close();
}

async function verifyPermissions(handle) {
  if (await handle.queryPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  if (await handle.requestPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  return false;
}
document.body.addEventListener('dragover', function (e) {
  e.preventDefault();
});
document.body.addEventListener('drop', async function (e) {
  e.preventDefault();
  for (const item of e.dataTransfer.items) {
    if (item.kind === 'file') {
      let entry = await item.getAsFileSystemHandle();
      if (entry.kind === 'file') {
        fileHandle = entry;
        restoreFromFile();
      } else if (entry.kind === 'directory') {
        // handle directory
      }
    }
  }
});
openButton.addEventListener('click', openFile);
saveButton.addEventListener('click', saveFile);
</script>
</body>

Storing and Retrieving a File Handle using idb-keyval:

Storing file handles can be tricky, since they can't be unstringified, though apparently they can be used with IndexedDB and mostly with history.state. For this example we'll use idb-keyval to access IndexedDB to store a file handle. To see it work, open or save a file, and then reload the page and press the 'Restore' button. This example uses some code from https://stackoverflow.com/a/65938910/.

<body>
<script src="https://unpkg.com/idb-keyval@6.1.0/dist/umd.js"></script>
<div><button id="restore" style="display:none">Restore</button><button id="open">Open</button><button id="save">Save</button></div>
<textarea id="editor" rows=10 cols=40></textarea>
<script>
let restoreButton = document.getElementById('restore');
let openButton = document.getElementById('open');
let saveButton = document.getElementById('save');
let editor = document.getElementById('editor');
let fileHandle;
async function openFile() {
  try {
    [fileHandle] = await window.showOpenFilePicker();
    await restoreFromFile(fileHandle);
  } catch (e) {
    // might be user canceled
  }
}
async function restoreFromFile() {
  let file = await fileHandle.getFile();
  let text = await file.text();
  await idbKeyval.set('file', fileHandle);
  editor.value = text;  
  restoreButton.style.display = 'none';
}
async function saveFile() {
  var saveValue = editor.value;
  if (!fileHandle) {
    try {
      fileHandle = await window.showSaveFilePicker();
      await idbKeyval.set('file', fileHandle);
    } catch (e) {
      // might be user canceled
    }
  }
  if (!fileHandle || !await verifyPermissions(fileHandle)) {
    return;
  }
  let writableStream = await fileHandle.createWritable();
  await writableStream.write(saveValue);
  await writableStream.close();
  restoreButton.style.display = 'none';
}

async function verifyPermissions(handle) {
  if (await handle.queryPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  if (await handle.requestPermission({ mode: 'readwrite' }) === 'granted') {
    return true;
  }
  return false;
}
async function init() {
  var previousFileHandle = await idbKeyval.get('file');
  if (previousFileHandle) {
    restoreButton.style.display = 'inline-block';
    restoreButton.addEventListener('click', async function (e) {
      if (await verifyPermissions(previousFileHandle)) {
        fileHandle = previousFileHandle;
        await restoreFromFile();
      }
    });
  }
  document.body.addEventListener('dragover', function (e) {
    e.preventDefault();
  });
  document.body.addEventListener('drop', async function (e) {
    e.preventDefault();
    for (const item of e.dataTransfer.items) {
      console.log(item);
      if (item.kind === 'file') {
        let entry = await item.getAsFileSystemHandle();
        if (entry.kind === 'file') {
          fileHandle = entry;
          restoreFromFile();
        } else if (entry.kind === 'directory') {
          // handle directory
        }
      }
    }
  });
  openButton.addEventListener('click', openFile);
  saveButton.addEventListener('click', saveFile);
}
init();
</script>
</body>

Additional Notes

Firefox and Safari support seems to be unlikely, at least in the near term. See https://github.com/mozilla/standards-positions/issues/154 and https://lists.webkit.org/pipermail/webkit-dev/2020-August/031362.html

🌐
W3Schools
w3schools.com › jsref › prop_win_localstorage.asp
Window localStorage Property
The localStorage object allows you to save key/value pairs in the browser.
🌐
SitePoint
sitepoint.com › javascript
How do I write to a local file using javascript - JavaScript - SitePoint Forums | Web Development & Design Community
March 24, 2020 - window.localStorage.setItem(‘games’, games) and window.localStorage.getItem(‘games’), but I’d like to be able to write strings to a file on my computer. Would greatly appreciate some help especially a block of code which I could use directly to do that. ... Well you can say ‘the usual security concerns are not an issue’. Javascript does not understand you.
🌐
GitHub
gist.github.com › liabru › 11263260
Save a text file locally with a filename, by triggering a download in JavaScript · GitHub
A solution is to probably stick with manually downloading through the element appended somewhere. function appendDownloadableText(filename, string) { const data = new Blob([string]); const url = URL.createObjectURL(data); const a = ...
🌐
Reddit
reddit.com › r/learnjavascript › how can i save a json value from html/javascript in a json file locally?
r/learnjavascript on Reddit: How can I save a json value from HTML/JavaScript in a json file locally?
December 29, 2021 -

I want to save some numbers from a small program in a local JSON file.

Example:

const increaseButton = document.getElementById("increase-button")
const numberField = document.getElementById("count-field")
let myNum = 0
let myArray = []
increaseButton.addEventListener("click", increaseNum)

function increaseNum() {
    myNum++
    numberField.innerText = myNum
    myArray.pop()
    myArray.push(myNum)
    let jsonString = JSON.stringify(Object.assign({}, myArray))
    console.log(jsonString)
}

The jsonString should be saved in a local file "myjson.json".

Goal: If I increase the number with the increaseButton, the new value should be saved in the "myjson.json" file:

{
    "numbers": {
        "0":1}
}

The only option I found was with node.js plugin "fs" and a lot of code. Couldn't it be easier?