Angelica.
← all resources

Stop losing the links people send you

ai prompt pack

Someone sends you a post worth keeping. You save it. Six weeks later you know you saved something about this and you cannot find it anywhere: not in the app's own saves, not in your notes, not in the twelve tabs. I stopped trying to fix that with another Notion database and built a small thing that does one job. It is called Shelf, and you can have your own in ten minutes or in an afternoon.

Two versions on this page. Basic is one file that opens from your own machine, no accounts, no hosting, done before your coffee goes cold. Pro is the one I actually use: your library lives in your own Google Drive, a browser extension saves posts with their captions, and you can file things from your phone. Compare them below, pick one, and the rest of the page changes to match.

before the how

What Shelf is, either way

One home for the links, docs and PDFs people send you. A card grid you can search, filter and open. Nothing revolutionary — the point is that it fits how you actually save things, because you are the one who specified it.

Both versions share the same three decisions, and the first one is the reason it stays usable six months in rather than being abandoned by week three.

Three labels, not one tag soupTopic is what it is about. Type is what you will do with it. Source is where it came from, read off the URL automatically and never asked. Three different questions, kept apart. Collapse them into generic tags and you get the same mess you already have.
Saving has to be nearly freeEvery save-it-later tool dies at the same point: the moment saving costs more than a couple of taps. This is where Basic and Pro genuinely differ, and it is the thing to weigh.
It is yoursNo account, no subscription, nothing of yours on anybody's server. Basic keeps everything in your browser. Pro keeps it in your own Drive. Neither one has a company in the middle that can change the terms.

side by side

Which one to build

  Basic Pro
Time to a working thing10 minutesan afternoon
Nothing to sign up for, nothing to deploy✓yes✗no
Save links, Google Docs and PDFs✓yes✓yes
Search, topic and type filters, favourites✓yes✓yes
Reader view, light and dark themes✓yes✓yes
Export everything as a backup file✓yes✓yes
Survives clearing your browser✗no✓yes
Same library on laptop and phone✗no✓yes
Browser extension: saves the caption and your highlight✗no✓yes
Save straight from your phone's share sheet✗no✓yes
Posts and videos playing inside the reader✗no✓yes
Add and rename your own topics from the app✗no✓yes
Undo a deletion✗no✓yes
Files larger than about 3 MB✗no✓yes

Two honest sentences to decide on. Basic is not a demo — it is a real tool, and if your saving happens at a desk it may be all you ever need. Pro exists because mine did not: the things worth keeping arrive on my phone, and a library I can only add to from one laptop is a library I stop adding to.

If you are undecided, build Basic today. It takes ten minutes, and a week of using it will tell you exactly which of those crosses you actually mind.

pick one

Which version are you building?


the ten minute version

Basic

One index.html with everything inside it. You open it by double-clicking the file. There is no server, no account, no hosting bill and nothing to keep running. Your library lives in that browser, on that machine.

Paste the prompt below into Claude, ChatGPT or whatever writes code for you, and ask for the file.

the basic build prompt
Build me a single-file personal content library called Shelf. One
index.html with the CSS and JavaScript inline. No framework, no build
step, no server. I open the file from my own machine and it works.

WHAT IT IS
One home for the links, Google Docs and PDFs people send me, so they
stop getting lost. Tagline: everything worth keeping, in one place.

ONE SAVED ITEM
id, title, url, source, type, topic, purpose (one line on why it is
worth keeping), summary (longer notes, becomes the reader body),
savedAt, fav.

Keep topic, source and type as three separate things. They answer
three different questions: what it is about, what I will do with it,
and where it came from. Do not merge them into one tags field.

- Topics, seeded: Marketing, Design, AI, Productivity, Life, Finance.
  Each gets its own colour from a shared palette.
- Types, seeded: Guide, Template, Checklist, Tool, Reference.
- Source is never asked for. Read it off the URL: Threads, Instagram,
  YouTube, TikTok, X, Substack, LinkedIn, Reddit, GitHub, Google Doc,
  Notion, PDF by extension, otherwise Web page. An uploaded file is
  always source File, whatever URL is attached to it.

ADDING SOMETHING
Drop a link or a file anywhere on the page, or press an Add button.
Both open the same form: link, title (suggested from the URL, I can
edit it), source shown as a read-only fact rather than asked, type,
topic, a one-line notes field, and a longer details field that becomes
the reader body. Only the title is required.

FINDING IT AGAIN
A left rail: full-text search over title and notes, multi-select topic
chips, single-select source and type built from what I actually have,
a favourites toggle, and a clear-all link that only appears when
something is on. A card grid: source badge, title, two-line excerpt,
coloured topic dot, type label, star button. Clicking a card opens a
reader view with the full notes and a link to the original.

STORAGE
Browser localStorage. No accounts, no server. Guard file uploads at
about 3 MB and say clearly when one is too big rather than failing
silently.

Give me an Export button that downloads everything as one JSON file,
so my library is never trapped inside a browser I might clear.

THE BAR
Light and dark themes, following my system setting, with a manual
toggle. Real copy everywhere, never placeholder text. Every colour
combination readable at WCAG AA. Everything reachable by keyboard with
a visible focus ring. No horizontal scrolling at any width. Respect
prefers-reduced-motion.

Build it, then tell me the first thing you would fix.
Where the idea came from. The one-file version of Shelf is not mine — it started as a prompt published by Automate Your Day, and their post is worth reading. I have not republished theirs here, because it is their work and their page. The prompt above is written from scratch to use the same field names as the Pro spec, so if you start here and outgrow it, you are extending something rather than starting over.

ten minutes, honestly

What you actually do

  1. Paste the prompt and ask for the file. Nothing else. Do not explain the project first; the prompt does it better than a chat window will.
  2. Save index.html somewhere you will find it. Not Downloads. Somewhere with a name, because this is a tool now, not an experiment.
  3. Double-click it. It opens in your browser and it is running. There is no step four to deploy anything.
  4. Bookmark it and put the bookmark on your bookmarks bar, at the far left. The whole design lives or dies on saving being cheap.
  5. Save three real things. Not test entries. Three links you would have lost, with real notes. Then export the JSON once, so you have seen where your backup lands.

what will eventually annoy you

The ceiling

Everything lives in one browser on one machine. That is fine until one of four things happens, and one of them will.

You clear your browsing data, or a cleanup tool does it for you, and the library goes with it. Export regularly or accept the risk knowingly.
Something arrives on your phone and there is no way to put it in. For most people this is the one that ends it.
You save an Instagram post and it arrives as a bare link with no caption, because a web page cannot read another website's contents. In a month you will not know what it was.
You want to add a topic that is not one of the six, and it means editing the file by hand.

None of that is a reason to skip Basic. It is a reason to export your JSON before you decide. When one of the four starts costing you more than an afternoon would, the Pro version is on the other tab.


the full version

Pro

This is the one I use. Three source files and a small build step, deployed to a free host, with your library in your own Google Drive and a browser extension feeding it. It is too long to copy off a page, so it comes as a file.

shelf-build-prompt.md Markdown · 19 KB · about 3,200 words Download

Not a prompt to tweak — a specification that walks the assistant through the build in five phases and stops at every point where it needs you. Open a new project in your coding assistant and give it the file whole. Do not summarise it, do not paste the interesting parts. Almost every line is a decision, and the ones that look like padding are usually the ones stopping a default you do not want.


what happens when

The five phases

The document tells the assistant to work in this order and to stop and show you the result at the end of each phase, rather than vanishing for an hour and returning with something that has never been run.

  1. The app, on your own machine, with no syncing yet. Everything in the browser's own storage. You get the add form, the grid, search, filters and the reader view. This is the phase where you find out you wanted the notes field bigger, or that you never use favourites. Change it here, while there is almost nothing to break.
  2. Deploy it. The assistant sets up the build, then hands back to you: connect the repo to Vercel, Netlify or GitHub Pages and copy the live address. This comes before the Google work and not after, because Google's setup asks for the exact address your app runs at, and until it is deployed you do not have one. Doing these two in the wrong order is the most common way to lose an hour here.
  3. Google Drive. Explained properly below. This is the fiddly one.
  4. The browser extension. Also below. It is what makes saving cheap enough that you keep doing it.
  5. Phone access, then the quality pass. The share-sheet setup, then the accessibility and quality checks run as an actual list, with a report of what passed rather than a claim that everything is fine.

phase three, properly

Why Google is in this at all

The app has no server and no database. That is the whole design: nothing to pay for, nothing to maintain, nobody who can shut it down or start charging you. But it means the library has to physically live somewhere, and the browser's own storage is not that somewhere — clear your cache, switch laptops, or open it on your phone, and it is gone. That is the ceiling the Basic version runs into.

So your Drive is the storage. The app creates one folder, keeps a single index file inside it holding your whole library, and puts any uploaded files there too. You can open that folder yourself and look at it. If you ever delete the app, your things are still sitting there.

Connecting it is the half hour that will annoy you. You are doing something that feels disproportionate — creating a project in Google Cloud Console, turning on the Drive API, filling in a consent screen, generating a client ID — for what is a personal tool. There is no shortcut. What you get for it is the permission scope: the app may see only files it created itself, and nothing else in your Drive. Not your documents, not your photos, not the tax folder.

One folder, created by the app, visible to the app. Everything else in your Drive stays invisible to it.
The origin you paste into Google must match your deployed address character for character. No trailing slash. This is what goes wrong.

You will also notice there is no password and no client secret anywhere. This flow does not use one, so if you find yourself hunting for a secret to paste in, you have taken a wrong turn in the console.


phase four, properly

What the extension is for

A web page is not allowed to read the contents of a different website. That is a browser security rule and a good one. But it means your app, sitting at its own address, cannot see the caption of the Instagram post you are trying to save, and most social platforms hand back nothing useful to the outside either. So without help, a saved post arrives as a bare link with no text, which makes it unfindable three weeks later — the exact problem you were solving.

The extension runs inside the page you are standing on, so it can see what the page says. It reads three things and passes them across:

The addressOf the actual thing. Right-click a link and it saves that link, not the page the link was sitting on. Right-click an image or a video and it saves that, not its container.
The descriptionThe title and description the page publishes about itself, which on social platforms often carries the author handle and part of the caption.
Anything you highlightedIf you selected text before triggering it, that wins over everything else. This is the one you will use most: highlight the two sentences that made you want to save it, and those are what you see later.

Three ways to trigger it, all doing the same thing: the toolbar button, the right-click menu, and a keyboard shortcut you set yourself. Set the shortcut. It is the difference between saving things and meaning to.

It cannot read your browser's own system pages, the extension store, or a PDF open in the viewer. On those it falls back to saving the plain address, which is the correct thing to do rather than failing.

the part I nearly left out

Using it from your phone

Most of what people send you arrives on your phone, which is also where you are least likely to open a laptop to file it. The app handles this without a mobile app existing, because it accepts an address of its own that carries the link you want to save.

The shape is ?add= followed by the link, with an optional title and text. Anything that can open a web address on your phone can therefore feed it.

  1. Add it to your home screen first. Open your deployed address in the phone browser and use "Add to Home Screen". It opens like an app, signed in, and that alone removes most of the friction.
  2. On iPhone, build a two-action Shortcut. In the Shortcuts app: a new shortcut, turn on "Show in Share Sheet" and set it to accept URLs. Then one Text action containing your address plus ?add= followed by the Shortcut Input, and one "Open URLs" action after it. Name it something short. It now appears in the share sheet of every app on the phone.
  3. On Android, it can register as a share target directly, so your app shows up in the normal share menu alongside everything else.
  4. Either way, ask the assistant to set this up with your real deployed address rather than working it out yourself. It is the last phase in the document and it takes two minutes with the URL in front of it.
Some share sheets do not fill the link field separately — they dump the whole thing, caption and all, into one blob of text. The app pulls the first link out of it rather than giving up. Small thing, and it is why the phone route works instead of half working.

the honest part

What you are accepting

Three limits, all stated in the document, none of them dealbreakers as long as you know about them going in.

The deployed page is publicly reachable. Anyone with the link sees an empty shell with a sign-in button and nothing else, because the data is in your Drive rather than on the page.
Edit the same item on two devices in the same second and the later write wins. This is a tool for one person. Solving it properly would cost more than the problem.
The extension cannot read browser system pages, the extension store, or PDFs. On those it falls back to saving the bare address.

None of these is a bug to be fixed later. They are the price of a thing with no server and no database, which is also why it costs nothing to run and why nobody can shut it down.


worth more than the app

How to write one of these for something else

You will build Shelf and then want a different small tool. The document is the transferable part, so it is worth knowing why the long version works when "build me a bookmarks app" does not.

  1. Say what it is in one sentence, before any technical detail. Everything downstream gets judged against that sentence. A spec that opens with the tech stack has already lost the thread.
  2. Name the data model early. What one record looks like is the decision every other decision hangs off. Write it down and half the ambiguity disappears.
  3. Say what you do not want. The line that keeps "Post" and "Video" out of the type list is doing more work than most of the feature descriptions, because it stops a default that would have arrived without being asked for.
  4. Explain the why for anything non-obvious. The paragraph about why the extension has to exist is not documentation, it is insurance. Without a reason, a capable assistant will helpfully decide the extension is redundant and drop it.
  5. State the quality bar as a requirement. Accessibility, real copy instead of placeholders, no horizontal scroll. Written down they get built in. Left out they get retrofitted, badly, by you, later.
  6. Document the limitation you are accepting. Otherwise you get an over-engineered answer to a problem you were happy to live with.
Build me a web app to save links, with tags and search. Make it look nice.
Six pages of decisions, including the four things it must not do and the one limitation you are fine with.

The second one is not harder to write. It is just written after you have thought about it, which is the actual work and always was.

If you build one, I would genuinely like to see it — send it over. I am curious which parts people change first, because that is where my version is wrong for everyone who is not me.