Browser extension guide
Install the grab extension on the machine you browse from.
The extension captures the magnet links and .torrent
downloads you click and hands them to putiorr. Install it from the
Chrome Web Store in one click, or from GitHub if you would rather load
it unpacked or pin a particular version. Either way it goes on the
computer running Chrome, not on the NAS running putiorr.
Before you start
Create at least one Putiorr Grab profile in the putiorr dashboard first. That preset is the only one the extension lists, and a grab aimed at any other preset is refused, so an install against a putiorr full of *arr profiles loads an empty profile list and cannot grab anything. The browser grabs section of the configuration guide covers creating one and listing the sites that route to it.
Everything about where a grab lands is configured in putiorr, on the profile. The extension holds a connection and a capture toggle, and shows putiorr's routing read-only.
putiorr normally runs in a container on a NAS, and Chrome runs on your laptop or desktop. Everything below happens on the machine with the browser: the extension is installed into Chrome, and it reaches putiorr over your network like any other client.
Install from the Chrome Web Store
The short path, and the one to take unless you have a reason not to. Chrome installs it, keeps it up to date on its own, and no folder has to stay anywhere on your disk.
Then carry on at Point it at putiorr — the two sections between here and there are about the unpacked route and do not apply to a store install.
The store carries the version Google has reviewed, which can sit behind the repository for a few days after a release. If you need a change that has just landed, take it from GitHub below rather than waiting.
Install from GitHub instead
Worth doing when you want to read what you are running, pin a
particular version, or run a change the store has not reviewed yet.
Every route here ends with a folder on disk that Chrome loads
unpacked; there is no .crx. The quickest is the packed
archive attached to a release.
Download the packed extension from a release
Each release on the
releases
page carries putiorr-grab-<version>.zip
under Assets — the extension alone, already
stripped of everything that is not part of it. Download it and
unpack it into a folder you intend to keep; that folder, the one
holding manifest.json, is what you load.
The number on the archive is the extension's version, from
its own manifest.json, and it moves independently of
putiorr's: a putiorr release that changed nothing in the extension
re-attaches the same number. The asset is built by the release
workflow, so releases published before that workflow existed have
no such file under Assets — take it from the newest release.
Clone the repository
Best when you already use git on that machine, because updating is then one command.
git clone https://github.com/ptheofan/putiorr.git
# the folder to load is putiorr/extension
Download a source archive
The fallback when the browser machine has no git and you want a
specific tag. Every tag has a source archive at a fixed URL — tags
are named vX.Y.Z, and .tar.gz works in
place of .zip:
https://github.com/ptheofan/putiorr/archive/refs/tags/<tag>.zip
# for example
https://github.com/ptheofan/putiorr/archive/refs/tags/v2.0.3.zip
The same archives are linked from each release, under
Source code. Do not confuse the two: a source
archive is the whole repository and unpacks to a folder named after
the tag without its leading v —
putiorr-2.0.3/ — and the folder to load is
putiorr-2.0.3/extension, not the folder above it.
Take the extension from the same version of putiorr you run. An
extension older than putiorr's browser-site routing sends a profile
id putiorr no longer wants; a putiorr older than the extension
answers an auto-captured click with
profileId is required, leaving only the right-click
menu working.
Where to keep the folder
Chrome does not copy an unpacked extension anywhere. It records the path you pick and reads the files from that path every time it starts, so the folder has to stay where it is, under the name it has, for as long as you use the extension. Unpacking an archive into a temporary folder or the Downloads folder you periodically empty is the way to arrive at an extension that stopped working and no obvious reason why.
The path is also the extension's identity. An unpacked extension carries no signing key, so Chrome derives its id from a hash of the folder's absolute path. Move or rename the folder — or a folder above it — and Chrome sees a different extension: a fresh install with empty options, alongside a broken entry pointing at the old path.
Pick somewhere permanent before you load it, such as
~/chrome-extensions/putiorr or a clone you keep
anyway. Getting this right once costs nothing; getting it wrong
costs the options and the site claims stored against the old id.
Load it in Chrome
- Open
chrome://extensions. - Turn on Developer mode with the toggle at the top right, and leave it on. Chrome 134 and later disable an unpacked extension whenever Developer mode is off, so this is a permanent setting rather than an install step.
- Click Load unpacked and select the folder that contains
manifest.jsonitself — the folder the release archive unpacked to, or the clone'sextension/directory — never the folder above it. - Reload any tabs that were already open. Pages loaded before the extension have no content script, so clicks on them are not captured. The right-click menu still works on such a tab, but the fetch is then made by the extension rather than by the page, without the page's session cookies, so a private tracker may refuse it.
The card that appears is named putiorr grab. Pin it to the toolbar if you want the popup that says which profile a grab from the current site would land in.
Point it at putiorr
Open the extension options — on chrome://extensions,
Details → Extension options — and
fill in the connection:
- Enter the putiorr URL, such as
http://nas:9091. It must be the root URL of the host, with no path, query, or fragment; putiorr cannot be served from a subpath, so a URL with one is refused rather than silently trimmed. - If putiorr sits behind Basic auth, fill in Username and Password. They are kept in local extension storage, not in the Google-account-synced storage that holds the rest of the settings — the privacy policy sets out exactly what is stored where, and the only two places the extension ever sends anything.
- Click Test connection & load profiles. putiorr answers with its Putiorr Grab profiles only, and the card lists what each one takes, including which one takes the sites no profile claims.
- Press Save. Loading only fills the page; nothing is stored until you save.
- Leave Auto-capture magnet and .torrent clicks on, or switch it off to grab exclusively through the right-click menu.
Then confirm it end to end: click a magnet: link on a
site one of your grab profiles claims. A
Downloading with putiorr… item appears at the top
right of the page, becomes
Downloading with putiorr using <profile>
profile, a matching Chrome notification arrives, and the
transfer shows up in the putiorr dashboard.
If the load returns nothing, the status says which of three things it was rather than guessing: no Putiorr Grab profiles exist, they all exist but are switched off, or the URL answered with something this page could not read — which is what another server's JSON at that address looks like from here.
Updating
A store install updates itself. Chrome fetches new versions on its own schedule and there is nothing to do — which is also why the first click in a tab that was already open may answer putiorr was updated — reload this page, then click again. An update replaces the extension but not the copies of its content script already sitting in open pages, so those pages have to be reloaded before they can capture anything. That message is the extension telling you so rather than failing silently; the file still downloads normally in the meantime.
An unpacked install never updates itself, and Chrome does not notice the folder changing while it runs. Updating that one is two steps, and the second is the one that is easy to forget:
- Refresh the files in place —
git pullin the clone, or unpack the new release archive over the same path so the path does not change. - Open
chrome://extensionsand click the reload icon on the putiorr grab card. The manifest, the service worker, and the content scripts are only re-read then. - Reload any tabs you had open, for the same reason as on a fresh install: their content script is the old one.
The options survive the reload. Keeping the same path keeps the same extension id, and the storage is keyed to that id, so the putiorr URL, the credentials, and the capture toggle are all still there afterwards. Run Test connection & load profiles again if profiles were added, renamed, or re-pointed in putiorr — the right-click menu is built from that cached list, while routing for ordinary clicks is resolved by putiorr on every grab and is correct immediately.
Unpacking a new version to a new path is not an update. It is a second extension with its own id and empty options, running beside the first. Remove the old card first if you have to move, and expect to set the options again.
What it does not do
- Chrome only. It is a Manifest V3 extension written against the
chrome.*APIs and has not been adapted or tested for other browsers. - Click capture recognises a path ending in
.torrent, or a link with a magnet in it. Trackers whose download URLs look likedownload.php?id=…are grabbed with right-click → Send to putiorr, which also overrides the profile for that one grab. - Links inside iframes are not captured. An embedded frame behaves as if the extension were not installed.
- Modifier clicks are never captured. Alt+click stays "download to disk", and is the escape hatch when you want the raw
.torrentfile. - A
.torrentis fetched by the page first, so private-tracker session cookies apply — and so does the page's CORS policy, which is what a link redirecting to a separate download host runs into. The extension then fetches it itself, which CORS does not apply to; that request carries noSameSite=Laxcookie, so a tracker that gates downloads on its session can still refuse it. Only when both fail does the click fall back to a normal browser download.
The extension's own README carries the full behaviour: what counts as a wrapped magnet, what every failure message means, and the endpoints it calls.