No signup. Nothing uploaded. PNG, SVG, vector PDF and EPS.
Seventeen kinds of QR code — a link, a WiFi network, a contact card, a WhatsApp message, a social profile, a UPI or SEPA payment, a crypto address, a location, a calendar event — styled with rounded or dotted modules, gradients, custom corners and your logo in the middle. Then the tool decodes its own output and confirms it reads back exactly what you typed. Download PNG, SVG, vector PDF, EPS or JPG. It all runs in your browser: nothing is uploaded, and the codes never expire.
Quick answer: pick a type, type your link or text, and a static QR code appears instantly. No signup, nothing uploaded, no expiry.
fetch, no XMLHttpRequest and no form — check it in your browser’s Network tab.The same code, laid out on a page at a known size, as a PDF rather than through the browser’s print dialog — so it comes out the size you asked for. Every label is the same vector page as the PDF download, scaled to the cell.
One link or line of text per row. Every code uses the style you set above, every one is decoded before it goes in the ZIP, and the whole thing runs here — a list of customer links or asset tags never leaves your machine.
Every row here is a plain fact about this generator, and each one is explained somewhere further down the page.
| Attribute | Value |
|---|---|
| Type | Static QR code generator |
| Cost | Free — no paid tier |
| Account or signup | Not required |
| File or data upload | None. Nothing is transmitted |
| Where it runs | Entirely in your browser (client-side JavaScript) |
| Code expiry | Never — the data is inside the pattern |
| Watermark | None |
| Scan limit | None |
| Commercial use | Permitted (terms) |
| Content types | 17 — see the table below |
| URL, text, email, phone, SMS | Yes |
| WiFi | Yes |
| vCard and MeCard contacts | Yes |
| Yes | |
| Location | Yes — maps link or geo: URI |
| Calendar event | Yes — iCalendar |
| Payments | Yes — UPI, SEPA/GiroCode, PayPal, crypto |
| PNG | Yes |
| SVG | Yes — true vector |
| Yes — true vector, exact physical size | |
| EPS | Yes — vector, for print shops |
| JPG | Yes |
| Transparent background | Yes |
| Logo in the centre | Yes — PNG, JPG, SVG or WebP |
| Colours, gradients, module shapes | Yes |
| Error correction | L, M, Q or H — selectable |
| Quiet zone | Adjustable, 0–10 modules |
| Frame with a call-to-action label | Yes |
| Printable sheet of labels | Yes — A4 or Letter, 2×2 to 4×4 |
| Bulk generation | Yes — up to 500 codes, downloaded as a ZIP |
| Scan verification | Yes — the page decodes its own output and reports |
| Maximum capacity | 2953 characters (level L); 1273 at level H |
| Dynamic or editable codes | No — why |
| Scan tracking or analytics | No |
| Reading a code back | Separate tools: scanner, validator |
Picking a type does not change the picture — it changes the text encoded inside it. A scanner reads that text and decides what to offer: a prompt to join a network, a contact to save, a payment to confirm. Get the format right and the phone does the work; get it wrong and the visitor sees a wall of punctuation.
| Type | What the phone does with it |
|---|---|
| URL | Opens the address. A shorter link makes a visibly less dense code. |
| Text | Shows the text, with no action attached — a reference, a serial, a note. |
| Opens the mail app with the address, subject and body filled in. | |
| Phone | Opens the dialler with the number ready to call. |
| SMS | Opens a new message to the number, text already written. |
| Opens a WhatsApp chat with your number, message ready to send. | |
| WiFi | Offers to join the network, no password typing. |
| Contact (vCard) | Offers to save a full contact card, including a structured postal address. |
| MeCard | The same idea with fewer fields, and a noticeably smaller code. |
| Location | Opens the map — as a maps link, or as a geo: URI. |
| Event | Offers to add an iCalendar entry to the diary. |
| Social | Opens your profile on the network you choose. |
| App | Opens your listing in the app store. |
| UPI | Opens an Indian payment app with your ID and name filled in. |
| SEPA / GiroCode | Opens a euro-area banking app with a prepared transfer to confirm. |
| PayPal | Opens your PayPal.me page. |
| Crypto | Opens a wallet on the send screen, with your address filled in. |
Each type has an address of its own — ?type=wifi, ?type=vcard and so on — so you can link straight to the form you want rather than telling someone which button to press. The formats with rules worth knowing before you print (vCard’s positional address, an all-day event’s end date, SEPA’s unlabelled lines) each have a page of their own, linked above.
Most of these are a link underneath — what changes is the physical situation the code has to survive. That is the part nobody tells you, so the third column is the one worth reading.
| Use | What goes in the code | What to watch in that setting |
|---|---|---|
| Business cards | vCard or MeCard | A full card with a postal address is already 0.385 mm per module at 25 mm — at the edge of what prints. Give a complete address 30 mm, or carry fewer fields. |
| Guest WiFi | Network name and password | The password is plain text inside the pattern. Anyone who scans it has it, so put the guest network on the card and never the main one. |
| Restaurant menus | A link to the menu page | Table codes are the classic target for a sticker placed over the top. Laminate them, and print the restaurant name beside the code so a wrong destination is visible. |
| Payments at a counter | UPI, SEPA/GiroCode, PayPal or crypto | Same sticker risk, with money attached. Print your own name next to it: most payment apps show the beneficiary before confirming, and that is the check that catches a swap. |
| Marketing and print ads | A link to the landing page | A shorter URL is a visibly less dense code. And a static code cannot be re-pointed, so aim it at a page on your own site and change what that page does. |
| Events and invitations | A calendar entry, or a registration link | If people need to book, link the registration page; a calendar entry puts the date in their diary but cannot take a booking. Use both, labelled, if you need both. |
| Product packaging | A link to instructions, spares or registration | Keep it on the flattest panel you have — curvature distorts the pattern and no amount of error correction fixes a bent code. Packaging is also where codes get printed smallest, so check the module size before the print run. |
| Property listings | A link to the listing or brochure | A window card is read from the pavement, through glass, often at an angle. Scanning distance scales with the size of the code, so a board meant to be read from two metres away needs a far bigger code than a leaflet does. |
| Equipment and asset labels | A link to the manual or a service log | These live in workshops and plant rooms. Error correction at Q or H buys tolerance for grease and scuffs — but keep the three corner squares clean, because damage there stops the code being found at all. |
Two of these deserve saying plainly. A QR code is not a security feature — it is a faster way to type an address, and it carries exactly the protection typing one would. And nothing here is tracked: these codes contain your destination rather than a link to our server, so we cannot tell you how many people scanned one, and nobody else can either. If you need scan counts, the counting has to happen at the page the code points to, using whatever analytics that page already has.
Every QR generator will hand you a black-and-white square. Almost none of them will tell you whether it works. This one decodes the picture it just drew, compares the result to what you typed, and says so — and it refuses to pretend a colour pair, a gradient or a logo is fine when we can measure that it is not. Every number below came from that testing: real codes, read back with ZXing, the engine most phone scanners descend from, cross-checked against jsQR.
One thing that surfaced while building it is worth passing on: decoders disagree about what is readable. jsQR cannot read a code whose modules are rounded by more than about a twentieth of a module — not because those codes are broken, but because that library does not handle them. ZXing reads every shape we tried. That is why the check in this page runs ZXing, in two configurations, and counts a code as readable if either one gets your content back.
The data modules can be rounded, turned into dots or set as diamonds, the corner frames can be square, rounded or circular, and the corner centres are styled and coloured separately. Gradients work too. What the tool will not do is restyle the three big corner squares as if they were data.
Those are the finder patterns, and they are how a scanner locates a code at all: it sweeps a line across the image looking for the run-length signature 1:1:3:1:1 — dark, light, three-wide dark, light, dark. Turn them into dots and that signature disappears. We tested it: a code with dotted finder patterns failed on both decoders, while the same code with dotted data and solid corners read at every size and fill we tried. Generators that let you round the corner squares are relying on the rounding staying mild enough not to matter; this one keeps them solid and lets you shape everything else.
Gradients are handled a little unusually here. Instead of painting a continuous colour ramp, the tool samples the gradient once per module and fills each shape with a single flat colour. At module scale you cannot see the difference, and it buys two things: the PNG, SVG, PDF and EPS become the same picture rather than four approximations of it, and every colour that ends up in your code is a colour the contrast check can measure. A gradient that starts dark and ends in something unreadable is caught, rather than passing because its first colour looked fine.
A QR code needs four empty modules of clear space around it. The standard says so, and it is the single most common way a code gets quietly broken — because on a white web page you cannot tell it is missing. Put that same code on anything else and it stops working.
We measured it. The same link, rendered with a 4-module quiet zone and with none, then placed on three backgrounds:
| Code sits on… | With 4 modules of margin | With none |
|---|---|---|
| a white page | scans | scans |
| a mid-blue panel | scans | scans |
| a dark background | scans | does not scan |
One module of margin was enough to bring the dark case back in our test, and four is what the standard asks for, so four is the default here. The slider lets you go lower — the tool will tell you what you are giving up.
Brand colours are where codes usually die. A scanner has to separate dark modules from light ones, and there is a point where it simply cannot. We stepped a grey foreground from black to white against a white background and decoded every step:
So this tool refuses anything under 4:1, and warns between 4:1 and 7:1 — a code in that band reads from a clean file, but it has no margin left for a phone camera, a cheap print run or bad light. For reference: a mid-blue like #5b6af5 on white is 4.4:1 and does scan; a warm yellow like #f5c45b on white is 1.6:1 and does not, which is the kind of code a generator without a check will happily hand you.
Light modules on a dark background — an inverted code — is a separate question. Many scanners cope; some refuse outright. The tool flags it rather than blocking it, because it is a real design choice, not a mistake.
This is the most repeated wrong thing about QR codes, and it is what breaks printed codes months after they were made. The error-correction level describes how many codewords can be reconstructed, not how much of the picture you may paint over. A logo destroys a contiguous block, and a contiguous block wipes whole codewords at once.
We swept a centre block from 5% to 40% of the code's width, across three payload lengths and three error-correction levels, and recorded the largest one that still read back:
| Error correction | Content | Code size | Largest logo | Which is… |
|---|---|---|---|---|
| M | 21 characters | 25 × 25 | 11% | 1.2% of the area |
| M | 44 characters | 33 × 33 | 18% | 3.2% of the area |
| M | 106 characters | 41 × 41 | 23% | 5.3% of the area |
| Q | 21 characters | 29 × 29 | 20% | 4% of the area |
| Q | 44 characters | 33 × 33 | 23% | 5.3% of the area |
| Q | 106 characters | 49 × 49 | 34% | 11.6% of the area |
| H | 21 characters | 29 × 29 | 20% | 4% of the area |
| H | 44 characters | 37 × 37 | 30% | 9% of the area |
| H | 106 characters | 57 × 57 | 39% | 15.2% of the area |
Hold that last column against the level’s headline percentage. Level H “recovers 30%” — and the most a logo ever covered here was 15.2% of the area, on the longest payload. On a short link at the same level it was 4%. The two numbers measure different things: recovery is counted in codewords spread across the whole symbol, while a logo destroys a solid block in one place.
The table shows something else worth knowing: the level alone does not tell you. At M the workable size ran from 11% to 23% of the width, decided by nothing but how much content was in the code; at H, from 20% to 39%. A slider with a “safe” mark printed on it would be wrong in both directions.
So this tool does not print one. It decodes your actual code, with your actual logo, every time you move anything — and if it cannot read it back, it says so before you download it.
Upload a PNG, JPG, SVG or WebP. The exports disagree about what an image even is, so the file is decoded once and kept in three shapes — otherwise a logo that looks right on screen quietly goes missing from the file you send to a printer, which is exactly what this page used to do to an SVG.
| Download | How the logo is carried |
|---|---|
| PNG · JPG | Drawn onto the canvas, so it is whatever your browser decoded |
| SVG | Embedded as the original file, so a vector logo stays vector |
| Embedded as PNG or JPEG. Anything else — SVG, WebP — is rasterised first, because those are the only two image formats a PDF can hold | |
| EPS | Embedded as raw samples, flattened onto the background colour first, because PostScript has no transparency in an image |
The format is read from the file’s own header bytes, never from what the browser labels it: an image off a phone share sheet often arrives with no type at all, and a PNG mislabelled as a JPEG would abort the PDF download outright. Logos are capped at 512 pixels on the long side, which on a code printed 30 mm wide is already more detail than a printer resolves.
A logo needs the extra recovery, so dropping one in moves the level up for you. Not always to H, though, and that distinction is a real one: H holds only 1273 characters. Forcing it on a 1300-character contact card — which fits perfectly well at Q — turned “add a logo” into a capacity error, so the tool now picks the highest level the content actually fits in. A short link gets H; a long vCard gets Q; something near the ceiling stays where it is, because no level with more recovery could hold it.
More error correction means less room. These are the real byte-mode limits, and the character counter under the content box counts against the one you have selected:
| Level | Recovers about | Maximum characters |
|---|---|---|
| L | 7% | 2953 |
| M | 15% | 2331 |
| Q | 25% | 1663 |
| H | 30% | 1273 |
You will rarely get near them, and you should not want to: a code holding 2000 characters is 169 modules across, and printed on a business card each module is thinner than a hair. Long content belongs behind a short link.
Shorter content also encodes smarter. A phone number like +15551234567 uses numeric mode and comes out 21 modules across; the same length of mixed-case text needs 25. Typing a URL in capitals switches it to alphanumeric mode, which is why some printed codes look coarser than others.
A printed module has to survive ink spread, paper and a camera. The usual working rule is that no module should be under about 0.4 mm, and that a code scans from roughly ten times its own width away. What that means for a real code depends on how many modules it has — which depends on what you put in it:
| Printed width | Short link (25 × 25) | Typical link (33 × 33) | Scans from about |
|---|---|---|---|
| 20 mm | 0.61 mm per module | 0.49 mm | 20 cm |
| 25 mm | 0.76 mm | 0.61 mm | 25 cm |
| 30 mm | 0.91 mm | 0.73 mm | 30 cm |
| 40 mm | 1.21 mm | 0.98 mm | 40 cm |
| 80 mm | 2.42 mm | 1.95 mm | 80 cm |
The panel under the preview does this sum for whatever you have actually typed. For anything that goes to a printer, take the PDF — it is a real vector at 30 mm square, so a print shop can scale it without a single soft edge. The SVG is the same code for design tools; the PNG is for screens; the JPG exists because people ask for it, and it is the worst of the four for a QR code, because JPEG compression rings around exactly the hard edges a scanner is looking for.
They are all the same code. What differs is what survives being resized, and what a print shop can do with the file.
| File | Use it for | Why |
|---|---|---|
| PNG | Screens, slides, email, anything on the web. | Sharp edges, no compression artefacts, and transparency if you want the page colour behind it. |
| SVG | Anything that will be resized, and any design tool. | Vector — it redraws cleanly at poster size. This is the right file to hand a designer. |
| Print, at an exact physical size. | A PDF carries its own page dimensions, so 40 mm stays 40 mm. Printing a PNG leaves the size to whatever dialog opens. | |
| EPS | A commercial printer that asks for one. | Vector PostScript. Some print workflows still want it; most now take the PDF. |
| JPG | Only where a system refuses everything else. | JPEG compression softens the hard edges a decoder relies on. It is offered because some upload forms accept nothing else, not because it is a good idea. |
A caution worth repeating, because it was a real bug here and is the kind that hides: a logo that shows in the preview is not proof the logo is in the file. Until this was measured and fixed, a PNG logo reached the PDF and an SVG or WebP one silently did not — the preview looked perfect and the file sent to the printer had no logo in it. All five downloads are now built from one shared description of the picture, so they cannot disagree. If you change anything after downloading, download again rather than editing the file.
For a page of identical labels rather than one code, there is a printable sheet — A4 or Letter, 2×2 up to 4×4, with cut guides.
A bare square on a window tells nobody anything. A frame with a line of text under it does two jobs at once: it says this is a code, and it says what happens if you scan it. “SCAN ME” is a prompt; “SCAN FOR MENU”, “SCAN TO ORDER”, “SCAN TO PAY” are answers, and they are better.
The interesting part is where the frame is allowed to sit. A frame drawn tight against the pattern eats the quiet zone, and the quiet zone is not decoration — it is how a scanner knows where the code stops. We swept a frame stroke inward one module at a time, at two different margins and two stroke widths, and decoded at every step:
| Clear modules between the frame and the code | jsQR | ZXing |
|---|---|---|
| Two or more | reads | reads |
| One | reads | reads |
| None — the frame touches the pattern | fails | fails |
One clear module is the boundary, and it lands in the same place in every combination we tried. So the frame here is built entirely outside the quiet zone — it makes the image bigger rather than borrowing space from the code — and it cannot eat into the margin however you set the slider. The code keeps exactly the module size it had without a frame; it is the picture around it that grows.
Two things worth knowing before you send one to a printer. The label is real text in the SVG and the PDF rather than an outline, which is what lets a designer restyle it — but it also means it renders in whatever font the machine opening it resolves, so convert it to outlines in your design tool if the typeface matters. And in the PDF and EPS the label is set in Helvetica, one of the fonts every reader already has, so nothing is embedded and the file stays small; characters outside that font, an emoji among them, are dropped from those two formats rather than taking the export down with them.
Bulk generation is behind a login almost everywhere, and there is a structural reason for that rather than a commercial one: if the codes are drawn on a server, your list has to be sent to it, and a list is exactly the kind of thing that needs an account attached. Here the codes are drawn in your tab, so there is nothing to send and nothing to sign up for. Paste a list or open a .csv, and you get a ZIP.
That matters most for the lists people actually make in bulk. Table numbers for a restaurant are dull. A column of customer links, staff names, patient identifiers, asset tags or unlisted URLs is not — and pasting one into a website is a decision somebody may have to justify later. This page has no route to send it: the file is read with FileReader and the ZIP is assembled in the same tab.
Four things it does that are worth knowing:
qr-001 onwards, which sorts properly.It makes URL and text codes. A batch of WiFi networks or contact cards would need a column per field and a different format per type, and the single-code tool above does those properly — so this does not pretend to.
Most codes are self-checking: scan it, and either the right thing happens or it does not. Two types are not like that. They can decode flawlessly, character for character, and still be wrong — because what goes wrong happens after the scanner has finished its job. Both have a page of their own, because there is more to say than belongs here.
A WhatsApp number has to be in full international form, digits only, with no national trunk prefix. 07700 900123 and 44 7700 900123 are the same number to a person and different things to wa.me; the first one builds a link, scans perfectly, and tells the customer the number is invalid once they have already scanned it. The tool strips spaces, dashes, a leading + and an unambiguous 00 prefix, then flags what is left if it still looks like a national number, is too short to hold a country code, or runs past the fifteen digits an international number is allowed. It cannot tell you the number is on WhatsApp — that is a shape check, and finding out for real would take a request we do not make. More on WhatsApp codes, and what the pre-filled message costs in printed size →
A calendar event is checked here by parsing the payload with two real calendar libraries rather than by looking at the image. That is how we found three faults in our own first version: an event carrying only a name parses fine but cannot be placed on any calendar, so the tool now refuses to build one; an all-day event's end date is exclusive, so 20 June to 20 June is an event of zero seconds and the tool writes the 21st for you; and a timed event with no end has no length at all, so it is given an hour. More on event codes, time zones and printing an invitation →
The same code laid out on a page, as a PDF rather than through the browser’s print dialog. That is a deliberate choice: a print dialog decides its own margins and scaling, so “fit to page” quietly shrinks everything and a label you measured at 40 mm arrives at 37. A PDF carries its own page size, and the printer honours it.
Pick A4 or US Letter and 2 × 2, 3 × 3 or 4 × 4, add a title, a caption and a “SCAN ME” line if they help, and turn on cut guides if you are trimming by hand. On A4 that gives:
| Grid | Labels | Label size | Module size, typical link |
|---|---|---|---|
| 2 × 2 | 4 | 92 × 136 mm | 2.11 mm |
| 3 × 3 | 9 | 60 × 89 mm | 1.32 mm |
| 4 × 4 | 16 | 43 × 65 mm | 0.92 mm |
All three clear the 0.4 mm floor easily, though a long payload has many more modules to fit in the same cell — so the panel works the figure out for what you have actually built, before you download.
Worth saying how it is made: each label is the PDF download, embedded. Not redrawn at label size — literally the same vector page, placed nine times. That is the only way to be certain a label is the code you approved, and it is why the frame, the logo and the colours come along with no second implementation to keep in step. Every label carries the same code; for a sheet of different ones, the batch panel above gives you a ZIP to place yourself.
Three buttons under the downloads, for the times a file is more trouble than it is worth. Copy image puts the PNG straight on the clipboard, so it can be pasted into a slide, a chat or a document without a trip through the downloads folder. Copy contents copies the payload rather than what is in the boxes — for a WiFi code that is WIFI:T:WPA;S:Cafe;P:hunter2;;, which is what a scanner actually reads, and it is the quickest way to see what you have really made. Copy SVG hands over the markup as text, ready to paste into a design tool or straight into a page.
Two limits worth knowing, both the platform’s rather than ours. PNG is the only image a browser will put on the clipboard — ask for SVG and Chrome refuses outright, which is why the SVG button copies text instead. And some browsers do not allow an image on the clipboard at all; there the button says so and points at the PNG download, which is the same code.
Other generators offer QR codes for a PDF, an MP3, a photo gallery, a feedback form or an app that sends iPhones and Android phones to different stores. Those are not extra QR formats — a QR code holds text, and none of that is text. Every one of them works by uploading your file to the generator’s server, or by pointing the code at a redirect they control, and encoding a link to it.
That has three consequences worth knowing before you choose a tool. Your file leaves your device. The code stops working if that company folds, changes its pricing or retires the link — and it is printed by then. And the address inside your code belongs to them, not to you.
Nothing is uploaded here, so those types are not on offer, and we would rather say why than quietly leave them off the list. The substitute is straightforward and better: put the file somewhere you control, then make an ordinary URL code pointing at it. If you need a destination you can change later, put a redirect on your own domain and encode that — you get the editability without handing anyone else the keys to your printed code.
“Nothing is uploaded” is a claim every generator makes, so here is the specific version, which you can check yourself in about thirty seconds.
Open your browser’s developer tools, switch to the Network tab, and type a WiFi password into the field above. Watch what happens. The requests you will see are these, and no others:
| Request | When | Carries your content? |
|---|---|---|
| The QR library, from jsDelivr | Once, on the first code you make | No — a static file, identical for every visitor |
| A decoder, from jsDelivr | Only when you add a logo, style the code, or press Test | No — same static file, and it runs on the picture in your tab |
| A PDF writer, from jsDelivr | Only when you click the PDF button | No |
| A ZIP builder, from jsDelivr | Only when you make a batch of codes | No — your list is read and zipped in the tab |
| This site’s own header, footer and fonts | On page load | No |
| Analytics and an ad script | On page load, as on any page here | No — they never see the field contents |
The reason none of them can carry it is structural rather than a promise: this page contains no way to send anything. There is no fetch, no XMLHttpRequest, no sendBeacon, no WebSocket and no form in it. The code is drawn onto a <canvas> in your tab and every download is a blob: URL created in that same tab. We check for this on every build, because a claim like this is only worth making if something enforces it.
What that buys you in practice: a WiFi password, a private link, an unlisted contact card or a payment address can go into a code here without existing anywhere except your own machine. Type the same thing into a generator that renders the image on its server and it has been transmitted, whatever the page says underneath.
Two honest caveats. The library files come from a public CDN, so that CDN can see that a browser at your address asked for a QR library — not what you did with it. And this site runs analytics and an ad script like most free tools; they measure page views, not the contents of a text field. If neither is acceptable, the page works with them blocked.
If you have the opposite problem — a code you did not make and want to know what is inside — the QR code scanner reads one out of an image and shows you the destination as text before anything opens. It runs the same decoder this page already uses to check its own output.
Every code this page makes is static: the destination is encoded in the pattern itself. Nothing sits between the scanner and the thing you pointed at, so the code cannot be switched off, rate-limited, watermarked or lost when a company folds. There is no account behind it and no expiry. The trade is the obvious one — you cannot change where a static code points once it is printed.
A dynamic code is a different arrangement. The pattern holds a short link on the generator’s own domain, and that domain redirects to wherever you currently want it to go. That buys two real things: you can change the destination after the code is printed, and you get scan counts. It costs two real things in return. The code stops working the moment that redirect service does — a link shortener that shuts down takes every printed code with it, and that has happened to companies with a lot of signage in the field. And every scan passes through someone else’s server, which sees the scanner’s IP address and rough location.
We do not offer dynamic codes, and the reason is architectural rather than a roadmap item: running them means running a redirect service and a database, which means your destinations live on our servers. This page has no way to send anything anywhere, which is the property most of the rest of it is built to protect. If you genuinely need editable destinations or scan analytics, use a service built for it — and go in knowing that you are renting the code, not owning it.
If what you want is the ability to fix a mistake, the cheaper answer is usually to point the static code at a URL you control — a page on your own site — and change what that page does. You keep the redirect and nobody else is in the path.