I'm confused about when should either of them be used.

Assuming I have this URL: http://site.com/?getsomejavascript=1, which is dynamically generated javascript:

  • if I include the script with esc_url(add_query_arg('apples', 420)), I get http://site.com/?getsomejavascript=1&apples=420 and it breaks because of those #038; references

  • if I use esc_url_raw(add_query_arg('apples', 420)) I get the correct URL: http://site.com/?getsomejavascript=1&apples=420

but in the documentation I find out that esc_url_raw should only be used to escape URLs inserted in the database...

2 Answers 2


From the Codex entry for Data Validation: URLs:

esc_url( $url, (array) $protocols = null ) (since 2.8)

Always use esc_url when sanitizing URLs (in text nodes, attribute nodes or anywhere else). Rejects URLs that do not have one of the provided whitelisted protocols (defaulting to http, https, ftp, ftps, mailto, news, irc, gopher, nntp, feed, and telnet), eliminates invalid characters, and removes dangerous characters. Deprecated since 3.0: clean_url() This function encodes characters as HTML entities: use it when generating an (X)HTML or XML document. Encodes ampersands (&) and single quotes (') as numeric entity references (&, ').

esc_url_raw( $url, (array) $protocols = null ) (since 2.8)

For inserting an URL in the database. This function does not encode characters as HTML entities: use it when storing a URL or in other cases where you need the non-encoded URL. This functionality can be replicated in the old clean_url function by setting $context to db.

So, the primary differences appear to be:

  1. esc_url() encodes HTML entities, while esc_url_raw() does not
  2. esc_url() is intended for output, while esc_url_raw() is intended for database storage


Since you are either hard-coding (or saving/storing separately) the actual URL from the query string, and then appending the query string via [add_query_arg()][2], might it be better to escape your appended query string via esc_js(), rather than esc_url()?

For example:

add_query_arg( esc_js( 'apples' ), esc_js( '420' ), $myurl )
  • 2
    ok, but the esc_url() doesn't work properly when you have query arguments in a URL which you wanto to output Commented Mar 31, 2011 at 16:02
  • What about using esc_js() to escape just the data added via add_query_arg()? See edit in answer, above. Commented Mar 31, 2011 at 17:07
  • I didn't try it, but that doesn't make sense :) both esc_js('apples') or 'apples' will return apples. The problem is in add_query_arg when joins 'apples' with other arguments with & Commented Mar 31, 2011 at 17:15
  • Then, if the data are trusted (i.e. static), why escape at all? Commented Mar 31, 2011 at 18:18
  • I'm not entirely sure it's safe to not escape it. I'm basically including script using something like <script type="text/javascript" src="<?= $_SERVER['REQUEST_URI'] ?>'/?javascriptcode=1"></script> Commented Mar 31, 2011 at 19:41

Let’s clear the confusion between sanitize_url(), esc_url(), and esc_url_raw() functions.


**esc_url( *string* $url, *string[]* $protocols = null, *string* $_context = 'display' ): string**


**sanitize_url( string $url, string[] $protocols = null ): string**

implementation of sanitize_url() is:

function sanitize_url( $url, $protocols = null ) {
    return esc_url( $url, $protocols, 'db' );


**esc_url_raw( string $url, string[] $protocols = null ): string**

implementation of esc_url_raw() is:

function esc_url_raw( $url, $protocols = null ) {
    return sanitize_url( $url, $protocols );

Conclusion: sanitize_url() and esc_url_raw() both function implementation is same, and it uses the esc_url() function with context parameter ‘db’.

Use: sanitize_url() and esc_url_raw() is used to sanitize a URL for database or redirect usage.

  • @onetrickpony This should be the accepted answer Commented Jan 9 at 3:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.