Online Notepad Persistence Model: What the Saved Label Actually Guarantees

An online notepad shows a green Saved indicator and people trust it like a file on

disk. The label promises less than they assume. We built the tool, and this article

documents its persistence model exactly as the code implements it, including the half

second window in which your last keystrokes exist only in memory.

Where the note lives

The notepad stores one note as one plain text string under one localStorage key,

wr-notepad-content. There are no multiple notes, no folders, and no format. The

storage belongs to the browser profile that created it. The same site in a different

browser, a different profile, or a different device starts with an empty notepad,

because none of them share that storage.

The note loads once, when the component mounts, inside the state initializer. If the

read throws, which happens when storage is blocked, the tool starts from an empty

string and shows no error.

The 500 ms save window

Saving runs on a 500 millisecond debounce. Each keystroke resets a timer, and only

when you stop typing for half a second does the tool write the text to localStorage.

The indicator switches to Saving on the first keystroke and back to Saved after the

write.

The window has a hard edge. The cleanup effect that runs when the component unmounts

cancels the pending timer without writing. There is no beforeunload handler either.

Follow the sequence and you see the exposure:

1. Type a character.

2. Close the tab, or navigate away, within 500 ms.

3. The timer dies before it fires, and the character was never written.

Anything you typed after the last completed save is gone. In normal writing this costs

you a word at most. In fast capture, a phone number pasted and immediately lost, it

costs the whole note.

When Saved does not mean saved

The save call is wrapped in a try/catch that ignores errors, including quota

exceeded. After the failed write, the code still sets the state to Saved. The

indicator therefore reflects that a save was attempted, never that it succeeded.

Two conditions produce silent failure in practice. Browser storage quotas reject

writes when the origin has filled its allocation, and private browsing modes or

storage-blocking settings can reject every write. In both cases the notepad keeps

working, keeps showing Saved, and keeps nothing.

Treat the indicator as a debounce signal. Treat the download button as the only

durable save.

How the counters count

The stats row computes four numbers with four different rules, and each rule has a

known edge:

  • Characters is the UTF-16 length of the text. An emoji counts as 2, because it

occupies two code units.

  • Words trims the text, then splits on any run of whitespace. An empty note is 0

words. Hyphenated words and contractions each count as one word.

  • Lines splits on newline characters. An empty note is 0 lines, a single character is

1 line, and a trailing newline adds one more line to the count.

  • Paragraphs splits on blank lines, then discards empty pieces. Single newlines do

not start a new paragraph.

The line rule is the one that surprises people. A note ending in a newline reports

one line more than the lines you can see.

Getting the note out and wiping it

Export is deliberately boring. The download button builds a text/plain blob with

UTF-8 encoding, names it notepad.txt, and triggers a download through a temporary

object URL that the code revokes immediately after the click. The copy button writes

the full text to the clipboard through the async clipboard API and shows a

confirmation for 1.8 seconds. If the clipboard call rejects, the catch block swallows

it and you learn nothing, so verify pastes from pages where clipboard access is

restricted.

Clear asks for confirmation with a browser confirm dialog, then empties the state and

removes the storage key. There is no undo and no history. The note has no versions

anywhere, so recovery after a clear means it never happened.

Fullscreen is a CSS overlay rather than the Fullscreen API. It hides the page header,

moves the textarea to fill the viewport, and binds the Escape key to exit. It changes

nothing about persistence.

Limits you accept with this model

No sync exists between devices, so the transfer path is download on one machine and

open the .txt on the other. Clearing browser data for the site deletes the note, and

browsing modes that discard storage on exit delete it every session. The content is

plain text with no encryption, stored under the site origin, readable by any script

running on that origin. For anything sensitive or long lived, this tool is the wrong

drawer, and a file with a backup is the right one.

Checklist before you rely on the notepad

  • You stopped typing at least 500 ms before you close the tab.
  • You downloaded a .txt copy of anything you cannot lose.
  • You tested once in private browsing mode if you use it there.
  • You expect emoji to count as 2 characters and trailing newlines to add a line.
  • You never store passwords or keys in it.
  • You accept that clearing browser site data empties the note permanently.

The model is honest about what it is: fast capture with a local, single-copy,

best-effort save.

Measure the window yourself. Open the

[online notepad](https://webrecast.com/en/online-notepad), type a sentence, close the

tab within half a second, and reopen it to see what survived. If your result differs

from the behavior described here, report it with your browser, because the description

comes from the shipping implementation.