Rob Kendal Freelance WordPress Developer

![Blog header for the article on ](/img/saving to client-side files - blog post.png)

Another one of those 'born of an issue I stumbled across' sort of situations, I came across the need to save some data entered into a form (some configuration details into a textarea to be specific).

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.

The need for simple solutions

There is a great article (if not a little out of date by now) by Eli Grey on saving generated files on the client side that also discusses his excellent utility FileSaver.js, which utilises the very same canvas blob functions mentioned above.

However, for me, it seemed a little overblown to bring in another utility dependency to perform a really simple task of creating a small text file and stashing it on the client's machine.

A vanilla JS solution to client-side file saving

So here we are, a really simple way to create and save a file on the client side, from the browser, based on some information saved into a textarea.

First, the HTML...

<fieldset>
  <legend>Enter some config details</legend>
  <textarea></textarea>
  <button id="btnSave">save config</button>
</fieldset>

Which renders the following no-frills elements in the browser (styling not shown for simplicity):

Screenshot of the textarea and save button ready to save the file

Now, for the JavaScript:

const downloadToFile = (content, filename, contentType) => {
  const a = document.createElement('a');
  const file = new Blob([content], {type: contentType});
  
  a.href= URL.createObjectURL(file);
  a.download = filename;
  a.click();

    URL.revokeObjectURL(a.href);
};

document.querySelector('#btnSave').addEventListener('click', () => {
  const textArea = document.querySelector('textarea');
  
  downloadToFile(textArea.value, 'my-new-file.txt', 'text/plain');
});

What we've got going on here, is a plain, browser-native querySelector call that grabs our button with the id btnSave, attaches an event listener that fires on click — nothing too fancy here.

Where the magic (well, really simple magic) is in the 'downloadToFile' method above. We create a new anchor element and a new Blob object using the content and contentType arguments we passed in.

Next, we set the href element to the result of the URL.createObjectURL() method that creates a DOMString containing a URL that represents the file object we just made.

Finally, we trigger our new anchor element's click event, which kicks off the download process in the browser, before cleaning things up using the URL.revokeObjectURL() method.

See it in action

You can view the code in action in my CodePen, or below in a handy iFrame.

Wrapping things up

And that's it. Nice and simple, gets the job done. Sometimes, the most straightforward solution is the best one if you need something lightweight that just works.

You might also like these articles that use plain old JS and CSS:

Rob Kendal

About Rob Kendal

Rob Kendal is an award-winning freelance front-end developer and marketer who likes simple, organised thinking and making clever things. You can find him working on some things on GitHub and recording podcasts, such as The Front End. Say hi and follow me on twitter

Comments

Read more

Using WordPress as a headless CMS with Next.js

Using WordPress as a headless CMS with Next.js

In part 2 of the Getting Started with Next.js, we connect a headless WordPress CMS to Next.js and pull in blog post content using WPGraphQL

#JavaScript#WordPress#Static Sites#Next

read the full article

Configuring WordPress as a headless CMS with Next.js

Configuring WordPress as a headless CMS with Next.js

In part 1 of the Getting Started with Next.js, we're looking at how to use configure WordPress as a headless CMS to use with Next.js using WPGraphQL

#Static Sites#Next#JavaScript

read the full article

Replacing React's Redux library with the useReducer Hook

Replacing React's Redux library with the useReducer Hook

Redux can be a tricky concept to get. By using React's useReducer Hook we can replace complex Redux configurations and still use state management.

#React#Development#Tutorials#JavaScript

read the full article