Send files from your app straight to the machine.
Your users make the file in your software. Then they save it, find a USB stick and walk it over, every time they change something.
Add Send to WiFiDrive and the file lands on the stick that already lives in the machine’s USB port. They never leave your app.
- Works with any machine that reads a USB stick: no driver, nothing per brand.
- Nothing to run on your side: no server, no account, no API key.
- One line of JavaScript in a web app. Three HTTP requests anywhere else.
<script src="https://wifidrive.app/send.js"></script> <button onclick="WiFiDrive.send(exportFile(), 'rosa.pes')"> Send to WiFiDrive </button>
The whole integration for a web app.
From your button to the machine.
- 1Your user clicks Send to WiFiDrive.A tab asks which WiFiDrive gets the file. The first time, they input its address; after that, they pick it, and its page opens.
- 2They confirm.The page asks: “yourapp.com wants to add rosa.pes to MY-MACHINE.” They click Add, and the file uploads.
- 3Your app gets the result.You get the name the file was saved under, so you can tell them it’s there.
wifidrive-test.txt.
One line of JavaScript.
Load send.js and call it from your button’s click. It finds the WiFiDrive, asks your user and puts the file there.
<script src="https://wifidrive.app/send.js"></script> <button onclick="WiFiDrive.send(exportFile(), 'rosa.pes').then(show)">Send to WiFiDrive</button>
| The promise resolves to | Meaning |
|---|---|
{ok: true, path} | It’s on their WiFiDrive, saved as path. A name that was taken gets a number, rosa-2.pes: nothing is ever replaced. |
{ok: false, error} | It failed. error is a sentence written for your user; show it as is. |
{ok: false, cancelled: true} | Your user clicked Cancel. |
{ok: false, closed: true} | Your user closed the tab before it finished. |
Call it in the click itself, before any await. It opens the tab first and waits for the file after, so pass a Blob, or a promise of one when your export takes a while. A tab opened later is a pop-up, and Safari blocks it.
It doesn’t work on a page that sends Cross-Origin-Opener-Policy: same-origin. That header cuts the link to the tab, so the file can’t reach it. Use same-origin-allow-popups instead.
Rather not load send.js? The messages.
Open https://wifidrive.app/send/ from your click. It asks your user which WiFiDrive gets the file and passes it on, and then:
| From | Message |
|---|---|
/send/, on load, to its opener | {wifidrive: 'ready', v: 1} |
| Your page, to that window | {wifidrive: 'file', v: 1, path, file} |
/send/, to yours | {wifidrive: 'result', v: 1, ok, path | error | cancelled} |
Answer its ready with the file.
Or let your assistant write it
Add a "Send to WiFiDrive" button beside this app's export. Read https://wifidrive.app/developers/ first: it is the whole contract.
- Load https://wifidrive.app/send.js with a <script> tag. Don't copy, bundle or install it.
- In the click handler, call WiFiDrive.send(file, name) before any await. file is a Blob, or a promise of one; name includes the extension.
- On {ok: true, path}, show that it was sent as path. On {ok: false, error}, show error as it is. Otherwise show nothing.
- Never ask for the WiFiDrive's address, and never call it yourself.
- If this app sends Cross-Origin-Opener-Policy: same-origin, stop and tell me: it can't work there.
Three HTTP requests.
Your user tells your program where their WiFiDrive is, once. Then one POST takes it from the machine, one sends the file, and one hands it back.
1. Ask for the WiFiDrive’s address, once
Fill in http://wifidrive.local/: it is right for a single WiFiDrive that was never renamed. A renamed one answers at its own name, http://my-machine.local/, and any one at its IP address. Keep what your user types, and let them change it.
2. Send the file
DRIVE=http://wifidrive.local
curl -d to=wifi "$DRIVE/api/mode"
curl --data-binary @bracket.nc "$DRIVE/api/upload?path=bracket.nc"
# {"ok":true,"size":18342,"path":"bracket.nc"}
curl -d to=usb "$DRIVE/api/mode"
The body is the file. path can name folders, Jobs/bracket.nc, and missing ones are created. DRIVE is the address your user gave.
"retry": true means the machine is reading the WiFiDrive. Ask again a second later, and show your user that it is waiting.
The answer names the file. With "ok":true, its path is where it was saved: a taken name gets a number, never a replacement. {"ok":false,"error":…} is a sentence for your user, to show as it is.
Send from your program’s own code, not from a web view. A request from an Electron or Tauri window, or any embedded page, is a browser’s: the WiFiDrive refuses it, and the browser would hide the answer anyway. Use Electron’s main process, Tauri’s Rust side, or your platform’s HTTP client.
Or let your assistant write it
Add "Send to WiFiDrive" beside this program's export. Read https://wifidrive.app/developers/ first: it is the whole contract. - Ask the user once for the WiFiDrive's address, with http://wifidrive.local/ filled in. Keep it, and let them change it. - From the program's own code, not a web view: POST to=wifi to <address>/api/mode, then POST the file's bytes to <address>/api/upload?path=<URL-encoded name>. - An answer with "retry": true means the machine is reading it: ask again a second later, and show that it waits. - On "ok": true, show the "path" it was saved as. On "ok": false, show "error" as it is. - When done, POST to=usb to <address>/api/mode the same way. - Use the language's standard HTTP client. Add nothing else.
Before you build
Does the file go through your servers?
No. It goes from your user’s computer straight to their WiFiDrive. With Remote access it passes through our relay, which keeps nothing.
What if a file with that name is already there?
A number is added (rosa-2.pes), and the result tells you the name. Nothing is overwritten.
What if the machine is using the WiFiDrive at that moment?
In a web app, the WiFiDrive’s page waits and uploads when the machine is done. From a program, you get "retry": true and ask again.
What do my users need?
A WiFiDrive in the machine and a computer on the same network. In a web app, with Remote access, any network.
Will it change under me?
No. What works today keeps working; anything added is optional.
Can I use the WiFiDrive name?
Yes. Label the button Send to WiFiDrive.
Does it cost anything?
No.
Shipping it? Tell us.
Write to us with questions, about a machine that misbehaves, or when your integration is ready.