Redirect
Ends the request with an HTTP redirect to the supplied address. Runtime-proven on a live Marketing Cloud Engagement CloudPage — a real 302 with the value passed straight into the Location header, and nothing like the similarly named RedirectTo.
Syntax
Redirect(url) → void
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
url |
string | number | Yes | Target URL |
Example
%%[
VAR @id
SET @id = QueryParameter("id")
IF Empty(@id) THEN
Redirect("https://example.com/pick-a-product")
ENDIF
]%%
<p>Product %%=v(@id)=%%</p>
When the guard fires the visitor’s browser receives an HTTP 302 pointing at the fallback address and the paragraph is never sent. When it does not fire the page renders as usual.
The address is handed on untouched, query string and all:
%%[ Redirect("https://example.com/offer?a=1&b=2") ]%%
The Location header of the response carries exactly https://example.com/offer?a=1&b=2.
Return value
void — nothing is returned. The whole response is replaced by a short server-generated redirect body; there is no value to assign or print.
Behaviour
A genuine HTTP 302. Fetched with automatic redirect following switched off, the response line is 302 Found and the Location header holds the supplied address character for character, ampersand included. No rewriting, no tracking wrapper.
Everything written before the call is discarded. Marker lines written immediately before the call — and a control line at the very top of the page that renders on every other request — were all absent from the response body. The body is only the short generated redirect notice.
Nothing after the call runs. The marker placed after the call never appeared.
The value is not validated as a URL. A bare number is accepted and lands in Location as a relative path. An empty argument is the one input that is not usable: it aborts the request with HTTP 422 instead of redirecting.
Exactly one argument. A zero-argument call and a two-argument call each abort the request with HTTP 422, while every other branch of the same deployment still answered 302.
How this differs from RedirectTo
Both were pointed at the same address in the same deployment and fetched the same way. They have nothing in common beyond the name:
| Redirect | RedirectTo | |
|---|---|---|
| Status | 302 | 200 |
Location header |
the supplied address | none |
| Body | short generated redirect notice | the page, rendered normally |
| Output written before it | discarded | delivered |
| Code after it | not reached | runs |
| Returns | nothing | the supplied address |
So they are trivially distinguishable from outside. If you want a visitor moved to another address, this is the function; RedirectTo only marks a URL for click tracking inside a send.
Show test script
%%[
VAR @b, @s
SET @b = RequestParameter("b")
/* known-good control: renders on every request, so a run of HTTP 422s
can be told apart from a broken deploy */
OutputLine(Concat("CTRL=[", Uppercase("ok"), "]"))
OutputLine(Concat("GATE=[", @b, "]"))
/* neither marker is delivered: the body is replaced by the short
server-generated object-moved payload */
IF @b == "rd" THEN
OutputLine(Concat("--- rd start ---"))
OutputLine(Concat("RD_BEFORE=[written-before]"))
Redirect("https://example.com/probe-target?a=1&b=2")
OutputLine(Concat("RD_AFTER=[written-after]"))
OutputLine(Concat("--- rd done ---"))
ENDIF
/* the very same target through RedirectTo, so the two can be compared
in one deploy: this one answers 200 with no Location header */
IF @b == "rt" THEN
OutputLine(Concat("--- rt start ---"))
OutputLine(Concat("RT_BEFORE=[written-before]"))
SET @s = RedirectTo("https://example.com/probe-target?a=1&b=2")
OutputLine(Concat("RT_RET=[", @s, "] LEN=[", Length(@s), "]"))
OutputLine(Concat("RT_AFTER=[written-after]"))
OutputLine(Concat("--- rt done ---"))
ENDIF
/* a bare number is accepted and becomes the Location as a relative path */
IF @b == "rdnum" THEN
OutputLine(Concat("RDNUM_START=[x]"))
Redirect(42)
OutputLine(Concat("RDNUM_DONE=[x]"))
ENDIF
/* an empty target is not usable: it aborts instead of redirecting */
IF @b == "rdempty" THEN
OutputLine(Concat("RDEMPTY_START=[x]"))
Redirect("")
OutputLine(Concat("RDEMPTY_DONE=[x]"))
ENDIF
/* argument counts the signature does not allow: each aborts its own
branch while every branch above still answers 302 */
IF @b == "rd0" THEN
OutputLine(Concat("RD0_START=[x]"))
Redirect()
OutputLine(Concat("RD0_DONE=[x]"))
ENDIF
IF @b == "rd2" THEN
OutputLine(Concat("RD2_START=[x]"))
Redirect("https://example.com/probe-a", "https://example.com/probe-b")
OutputLine(Concat("RD2_DONE=[x]"))
ENDIF
]%%
Landing pages are the only context: the function has nothing to act on in an email, and that case was not exercised here.
Availability
| Platform | Available |
|---|---|
| Marketing Cloud Engagement | Yes |
| Marketing Cloud Next | No |
See also
- RedirectTo — the confusingly similar name that emits no redirect at all
- RaiseError — the other page-terminating Utility function, which ends the request with a failure instead
- Official reference · ampscript.guide