# Draft menu entries

**URL:** <https://discourse.gohugo.io/t/draft-menu-entries/54622>\
**Category:** support\
**Created:** [May 4, 2025, 3:01pm UTC](https://discourse.gohugo.io/t/draft-menu-entries/54622 "2025-05-04T15:01:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmahnke](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/cmahnke/32/14148_2.png) [@cmahnke](https://discourse.gohugo.io/u/cmahnke)\
**Post date:** [May 4, 2025, 3:01pm UTC](https://discourse.gohugo.io/t/draft-menu-entries/54622/1 "2025-05-04T15:01:17Z")

</div>

I’m currently looking into the completeness of the `draft` mode: According to [Menus](https://gohugo.io/content-management/menus/) there is no flag to indicate that a menu entry shod be only generated in `draft` mode. Is the documentation complete or is this a missing feature?

I didn’t try but would like to know if this would be feature other would like to see as well. For now I solved it myself by using the following in the menu entry:

```auto
params:
      draft: true

```

And then in the template:

```auto
      {{- with .Site.Menus.main -}}
        {{- range sort . -}}
          {{- if and .Params.draft (not hugo.IsDevelopment) -}}
            {{- continue -}}
          {{- end -}}
        {{- end -}}
     {{- end -}}

```

But this is a workaround since this hits another missing feature, the seems to be no method to check for `draft` mode?!

That can’t be right, I must be missing something…

---

<div class="post-metadata">

**Author:** ![irkode](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/irkode/32/26135_2.png) [@irkode](https://discourse.gohugo.io/u/irkode)\
**Post date:** [May 4, 2025, 6:37pm UTC](https://discourse.gohugo.io/t/draft-menu-entries/54622/2 "2025-05-04T18:37:49Z")

</div>

Draft is a page attribute and pages where this is true will be ignored unless you use --buildDrafts.

so as you guessed you will have to implement that yourself.

this works fine for me using a site generated with `hug new theme --themesDir . mysite`

##### adjusted menu entry for _Tags_

````toml
[menus]
   [[menus.main]]
      name = 'Tags'
      pageRef = '/tags'
      weight = 30
      [menus.main.params]
         draft = true```

````

maybe check your YAML indentation/ Syntax

```yaml
menus:
  main:
    - name: Tags
      pageRef: /tags
      weight: 30
      params:
        draft: true

```

##### menu template

```auto
<nav>
   <ul>
      {{- with site.Menus.main }}
         {{- range sort . -}}
            {{- if .Params.draft -}}
               {{- continue -}}
            {{- end -}}
            <li>{{ .Name }}</li>
         {{- end -}}
      {{- end -}}
   </ul>
</nav>

```

the _Tags_ menu entry is not rendered

check your context `.`

---

<div class="post-metadata">

**Author:** ![cmahnke](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/cmahnke/32/14148_2.png) [@cmahnke](https://discourse.gohugo.io/u/cmahnke)\
**Post date:** [May 4, 2025, 6:53pm UTC](https://discourse.gohugo.io/t/draft-menu-entries/54622/3 "2025-05-04T18:53:45Z")

</div>

@irkode Thanks, but that doesn’t really address my points. My solution is already working, but it’s not what one might expect.

The first question: Might it be a worthwhile addition to add a draft mode to menu entries as well?  
The second question (and you example falls short in this regard): How does one trigger the `.Params.draft` when in draft mode? I used `(not hugo.IsDevelopment)` which in general matches the behaviour I expect but is just another work around, since one could also enter development mode without having the drafts build.

Is there no way to check in the template if we are in draft mode?

---

<div class="post-metadata">

**Author:** ![irkode](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/irkode/32/26135_2.png) [@irkode](https://discourse.gohugo.io/u/irkode)\
**Post date:** [May 4, 2025, 7:17pm UTC](https://discourse.gohugo.io/t/draft-menu-entries/54622/4 "2025-05-04T19:17:44Z")

</div>

oops, you’re right have been on the wrong track. sry

> [@cmahnke](#):
>
> Is there no way to check in the template if we are in draft mode?

to check if _buildDrafts_ is active we have:

> **[BuildDrafts](https://gohugo.io/methods/site/builddrafts/)**
>
> Reports whether the current build includes draft pages.

> [@cmahnke](#):
>
> Might it be a worthwhile addition to add a draft mode to menu entries as well?

That’s not a question for me to answer, but never heard such a request before.

usually one defines a menu or not maybe more details on the Use case will help to understand the need.

---

<div class="post-metadata">

**Author:** ![cmahnke](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/cmahnke/32/14148_2.png) [@cmahnke](https://discourse.gohugo.io/u/cmahnke)\
**Post date:** [May 4, 2025, 7:30pm UTC](https://discourse.gohugo.io/t/draft-menu-entries/54622/5 "2025-05-04T19:30:28Z")

</div>

@irkode Great, Thanks, that was actually what I was looking for. I was just looking at the wrong namespace, certainly because I was under the assumption, that it’s a command line setting like the environment ans those are under the `hugo` prefix / namespace ([Hugo functions](https://gohugo.io/functions/hugo/)).

Since menu Item are just links to existing content it shouldn’t be suprising that one might want to hide an entry. Just because the target could be missing. I guess it would be overkill to check agains the link target and hide an menu item when the target isn’t visible. On the other hand this would allow to hide menu items that have a target with a build date in the future. 😉

Thanks for your help!

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [May 5, 2025, 8:35pm UTC](https://discourse.gohugo.io/t/draft-menu-entries/54622/6 "2025-05-05T20:35:11Z")

</div>

When the menu entry specifies a `pageRef`, Hugo attempts to find a _published_ page with the corresponding logical path. Draft, future, and expired content is not published, so the menu entry’s [`.Page`](https://gohugo.io/methods/menu-entry/page/) method returns nil.

So you can exclude menu entries by wrapping the rendering code in a conditional. For example:

```plaintext
{{ with site.Menus.main }}
  <nav class="nav-inline menu">
    <ul>
      {{ range . }}
        {{ if .Page }} <---------------- begin conditional
          {{ if $.IsMenuCurrent .Menu . }}
            <li class="active"><a aria-current="page" href="{{ .URL }}">{{ .Name }}</a></li>
          {{ else if $.HasMenuCurrent .Menu . }}
            <li class="ancestor"><a aria-current="true" href="{{ .URL }}">{{ .Name }}</a></li>
          {{ else }}
            <li><a href="{{ .URL }}">{{ .Name }}</a></li>
          {{ end }}
        {{ end }} <---------------- end conditional
      {{ end }}
    </ul>
  </nav>
{{ end }}

```

You could also check for `.URL`, which will be an empty string if the page does not exist.
