Determining whether a user is currently viewing your homepage is one of the most common tasks you'll encounter when building with Craft CMS. Whether you need to hide the navigation bar, display a unique hero section, or load specific tracking scripts, knowing exactly how to identify the home URI is essential for a clean template structure.

However, many developers run into the dreaded Variable "entry" does not exist error when trying to perform this check inside a global layout file. This happens because not every page on a Craft site is an entry—some might be category pages, search results, or custom plugin routes. In this guide, you will learn the most robust methods to detect the homepage across Craft CMS 3, 4, and 5.

The Native Property: entry.isHomepage

If you are working within a template where the entry variable is automatically populated (like a Single or a Structure entry), Craft provides a built-in property specifically for this purpose. This is generally considered the cleanest and most readable method.

{% if entry is defined and entry.isHomepage %}
   <p>Welcome to the homepage!</p>
{% endif %}

Why use 'is defined'?

As mentioned in the community discussion, the most common pitfall is assuming the entry variable always exists. If you place your check in a global _layout.html file and then visit a page that doesn't have an associated entry (such as a custom controller route or a search page), your site will throw an error. Always wrap your check in an if entry is defined block to ensure template stability.

Checking the Internal URI

Craft CMS uses a special internal designation for the homepage URI: __home__. Regardless of what your site's URL structure looks like, Craft recognizes the homepage entry by this specific string. This is a highly reliable way to check for the homepage if you prefer to look at the URI property directly.

{% if entry is defined and entry.uri == "__home__" %}
  <p>This is the homepage entry.</p>
{% endif %}

You can also write this as a concise one-liner for setting a boolean variable at the top of your template:

{% set isHomepage = (entry is defined and entry.uri == "__home__") ? true : false %}

The Request-Based Approach (URL Detection)

Sometimes you need to detect the homepage based on the URL rather than the entry object. This is particularly useful when you are dealing with complex routing or when the entry variable isn't available. You can use the craft.app.request object to inspect the current URL path.

Using pathInfo

The pathInfo property returns the URI of the current request. For the homepage, this is typically an empty string or a forward slash.

{% if craft.app.request.pathInfo == '' %}
    <p>You are on the homepage.</p>
{% endif %}

Using URL Segments

Another clever way to identify the homepage is to check for the existence of the first URL segment. If there are no segments in the URL, the user is at the root of the site.

{% if not craft.app.request.segment(1) %}
    <p>This is the homepage (no segments found).</p>
{% endif %}

Handling Multi-site and Localized Homepages

In a multi-site or localized setup, the homepage URL might change depending on the language (e.g., / for English and /fr/ for French). If you are checking the raw URL, you must account for the site handle or language prefix.

{% if craft.app.request.url == '/' or craft.app.request.url == '/' ~ craft.app.language %}
    <p>Localized homepage detected.</p>
{% endif %}

While this works, it is often better to stick to entry.isHomepage in multi-site environments, as Craft's entry object is already site-aware and will correctly identify the homepage entry for the current site context.

The "Pro" Method: Using the URL Manager

For a more advanced and robust check that works even when the variable name isn't entry (for example, if you've renamed your element variable in your section settings), you can query the urlManager directly. This checks if the element that matched the current request is indeed the homepage.

{% set matchedElement = craft.app.urlManager.matchedElement %}
{% if matchedElement and matchedElement.uri == '__home__' %}
    <p>Show this only on the homepage</p>
{% endif %}

Common Mistakes to Avoid

  1. Forgetting 'is defined': As discussed, this is the #1 cause of template errors in _layout.html. Never call a property on entry without checking if it exists first.
  2. Checking the Handle Only: Developers often try to check entry.section.handle == 'homepage'. While this works, it's brittle. If a client renames the section handle, your code breaks. Using entry.isHomepage is much more resilient.
  3. Hardcoding URLs: Avoid checking if craft.app.request.url == 'https://mysite.com/'. This will fail in local development or staging environments. Always use relative paths or native Craft properties.

Frequently Asked Questions

Why does entry.isHomepage return an error on my search page?

Because a search page is typically a custom route or a template-only page, Craft doesn't automatically provide an entry object to that template. To fix this, use {% if entry is defined and entry.isHomepage %}.

Does this work in Craft 5?

Yes! All methods mentioned here—specifically entry.isHomepage and the __home__ URI check—remain the standard approach in Craft 5.

How do I hide a navigation bar only on the home page?

In your _layout.html, you can wrap your navigation include in a conditional:

{% if entry is defined and entry.isHomepage %}
    {# Do nothing or show a special hero #}
{% else %}
    {% include '_partials/nav.html' %}
{% endif %}

Wrapping Up

Whether you use the native entry.isHomepage property or the more flexible craft.app.request object, detecting the homepage in Craft CMS is straightforward once you account for potential null variables. For most projects, the native property combined with an is defined check is the cleanest, most maintainable solution.

By following these best practices, you'll ensure your templates are error-free and performant, regardless of how many different entry types or custom routes your site uses.