How to Add a Favicon to WordPress (the Correct Way)

A stylized browser tab featuring a blue WordPress logo as the favicon with a coral arrow pointing to it. Text: ADD WORDPRESS FAVICON.

Adding a favicon to WordPress should take a minute, but most older tutorials still tell you to paste a <link> tag into your header, which only covers one icon and skips mobile. This DevAnswers guide shows the correct way: WordPress has handled favicons natively since version 4.3 through the Site Icon feature, and we cover both the built-in method and the programmatic options for theme developers.

For almost every site this is the right approach. The Site Icon feature works out of the box, is theme-independent, and does not require any theme support. From a single uploaded image it generates the standard browser favicon, the Apple touch icon for iOS home screens, and the icons other platforms expect, so you never hand-code a tag.

To set it, upload a square image of at least 512 by 512 pixels in the Customizer:

  1. In your dashboard, go to Appearance > Customize.
  2. Open the Site Identity tab.
  3. In the Site Icon section, click Select site icon and upload your image (crop it square if prompted).
  4. Click Publish to save.

That is it. WordPress stores the image as the site icon and prints all the required tags into your page head automatically. Because the feature is theme-independent, your favicon survives a theme switch, which a hard-coded tag would not.

Using a block theme (the default since WordPress 5.9)? The Appearance > Customize menu item may be hidden. You can still open the Customizer directly at your-site.com/wp-admin/customize.php, where the Site Icon control lives.

Method 2: Add a Favicon With Code 

If you build custom themes, manage assets in Git, or want a favicon that ships with the theme instead of a database option, you can add one in code. Output a <link> tag on the wp_head hook, which is the correct hook for adding tags to the document head. Add this to your theme’s functions.php file:

functions.php
function custom_theme_favicon() {
    $url = get_template_directory_uri() . '/assets/favicon.png';
    echo '<link rel="icon" href="' . esc_url( $url ) . '">';
}
add_action( 'wp_head', 'custom_theme_favicon' );

Always pass the URL through esc_url(). If a Site Icon is already configured, you can reuse it instead of hardcoding a path: get_site_icon_url() returns its URL, has_site_icon() checks whether one is set, and wp_site_icon() is the core function that prints the full set of icon tags on wp_head for you.

That single tag covers one icon. For the full modern set, run your logo through RealFaviconGenerator and download the package. Extract it and upload the files to a folder in your active theme (for example assets/favicons/), alongside your other theme assets, then add this function:

functions.php
function custom_favicon_tags() {
    $dir = get_template_directory_uri() . '/assets/favicons';
    echo '<link rel="icon" type="image/png" sizes="96x96" href="' . esc_url( "$dir/favicon-96x96.png" ) . '">';
    echo '<link rel="icon" type="image/svg+xml" href="' . esc_url( "$dir/favicon.svg" ) . '">';
    echo '<link rel="shortcut icon" href="' . esc_url( "$dir/favicon.ico" ) . '">';
    echo '<link rel="apple-touch-icon" sizes="180x180" href="' . esc_url( "$dir/apple-touch-icon.png" ) . '">';
    echo '<link rel="manifest" href="' . esc_url( "$dir/site.webmanifest" ) . '">';
}
add_action( 'wp_head', 'custom_favicon_tags' );

That is the current RealFaviconGenerator set: a scalable favicon.svg for modern browsers, with favicon-96x96.png and the legacy favicon.ico as fallbacks for browsers that do not render SVG favicons, the apple-touch-icon.png for iOS home screens, and site.webmanifest for Android and PWA installs. Keeping the files in the theme keeps them tidy and version-controlled with your CSS and JavaScript. One detail: the browser-tab and iOS icons work straight away, but RealFaviconGenerator writes the icon paths inside site.webmanifest as root-relative, so if you also want the Android and PWA install icons, set the path option in the generator before downloading (so it bakes in your theme path) or edit the src values inside site.webmanifest to match the folder. If site.webmanifest later shows 404 or 401 errors in your logs, see the site.webmanifest error fix. If you would rather not adjust anything, upload the files to your site root instead and swap get_template_directory_uri() . '/assets/favicons' for home_url( '/' ), which matches the generator’s defaults as is. Either way, the lowest-effort route is still Method 1, which generates every size from one uploaded image with no files or markup to manage. For other theme assets, see our guides to adding a custom CSS file the correct way and a custom JavaScript file the correct way.

Use a Different Favicon for the Admin Area 

A different favicon in the wp-admin dashboard lets you tell at a glance which browser tab is the admin and which is the live site. By default WordPress shows your Site Icon everywhere, including the dashboard (it hooks the icon tags onto the admin head as well as the front end and login screen), so a custom admin favicon means first removing WordPress’s own tag from the admin head, then adding yours. Add this to your theme’s functions.php file:

functions.php
function custom_admin_favicon() {
    // Remove WordPress's own Site Icon tag from the admin head,
    // whatever priority core registered it at.
    $priority = has_action( 'admin_head', 'wp_site_icon' );
    if ( false !== $priority ) {
        remove_action( 'admin_head', 'wp_site_icon', $priority );
    }
    $url = get_template_directory_uri() . '/assets/favicon-admin.png';
    echo '<link rel="icon" href="' . esc_url( $url ) . '">';
}
add_action( 'admin_head', 'custom_admin_favicon', 0 );

Your function runs first because of the priority of 0. has_action() returns the priority WordPress registered its own icon at, remove_action() takes it out at exactly that priority, and your <link> becomes the only favicon in the dashboard. The front end and login screen keep your Site Icon, an easy way to avoid editing the wrong site by mistake. Beyond icons, you can further personalize the dashboard by adding custom CSS to WordPress admin and login pages.

Summary 

The correct way to add a favicon in WordPress is the built-in Site Icon feature: upload a square image of at least 512 by 512 pixels at Appearance > Customize > Site Identity, and WordPress generates the favicon plus the apple-touch-icon and platform tags automatically. Only add one in code (a <link rel="icon"> on wp_head, escaped with esc_url()) when you need a theme-bundled icon and accept that it covers just one size. And if you want the dashboard to stand out from the live site, give wp-admin its own favicon on the admin_head hook.

Support DevAnswers
Written, tested and maintained by one developer. Your support keeps these guides accurate and ad-light.
Buy me a coffee

Comments

Leave a reply