Homepage as a a homepage template -- how?

Hi guys,

This is something basic I’m trying to get. The documents are clear (and so are the helpful video tutorials) but I’m not sure which documents/tutorial I should watch.

My template, hyde, comes with posts on the main (and only) page. I would like to have a static homepage showing instead, with some text like a welcome message and maybe an image instead. The key for this from what I see is to create a homepage template. But… how? What actually creates it? Do I need to create an html file myself from scratch, or am I producing something in markdown and HUGO will translate it?

In my public page generated by Hugo, already have index.html, and I do have my about in a different section already, but they both showed on the main blog page. Right now it’s removed.

Webiste is here: https://github.com/jarss/TAONAW

Thanks in advance!

You create a homepage template. To learn more about template, read the introduction.

Since you are modifying or adding templates, you should read up on all of them, so you know where each is used.

1 Like

It’s ok - it looks like you do have an index page (homepage) template in your theme, it just has the code to range through all the pages on the site - https://github.com/jarss/TAONAW/blob/master/layouts/index.html

You could remove the listing range code from that and adjust as you want to become your static homepage. If you need that specific range for other things, copy it onto “list.html” in /layouts/_default/ for now - then you can return to it later.

In /content/, you can put an _index.md file. This lets you define any front matter for your homepage, which you can call on the index.html template. _index.md in this folder will use the index.html template in the root /layouts/ automatically.

I’m a bit (ok more than a bit) lost here.

I understand the general concept of templates, for single vs list pages, and homepages. I took a look at my homepage template - the index.html in the layouts folder. But I don’t understand the shortcode and the functions used. I can’t find these elements in the Google documents, and I’m not sure what they do.

So, I don’t want to just mess it up. Eventually, I’ll start moving around stuff, but I feel like a blind guy feeling around for objects in the dark. Surely, there’s a better way?

{{ define “main” -}}
{{ range .Data.Pages -}}…

I’m not looking just for an answer as to what these do, I want to know where I find the answers so I can keep looking it up myself?


Your theme probably has a _default/baseof.html that defines the base of all layouts.

Your index.html then just (re)defines just the “main” block from that baseof.html (and everything else from that baseof stays that same).


It takes a while to get used to the Go templating language! The Hugo docs give basic guidance and some examples but posting here to understand more also helps. The doc link posted above should give more info on how the templating works.

I wrote two posts about this when I started with Hugo. Perhaps this helps (the second is a bit more advanced):


The following is my very basic understanding of what’s going on in my current home template, and how to change it to get what I want (which is a generic introduction text containing some links) instead of a list of posts from ALL sections, which is what I have now.

What I did is to look at basof, the hompage (index) template, and comparing to the rendered html in my public folder. I searched terms in hugo documents as I read through, using knowledge of what I read already.

Here we go:

My theme does indeed has a baseof, which I understand to be a fundamental building block that contains a “meta-template.” In my case:

{{ partial "head.html" . }}
  <body class="{{ .Site.Params.themeColor }} {{if .Site.Params.layoutReverse}}layout-reverse{{end}}">
  {{ partial "sidebar.html" . }}
    <main class="content container">
    {{ block "main" . -}}{{- end }}

This chunk is responsible for creating the color for the nav bar at the side (params.themeColor), of which I have 8 options, this is described in the theme’s page. It also contains instructions to include the sidebar and the content container, defined as “main”.

OK, so knowing that I can take a look at my index.html inside layouts:

{{ define "main" -}}
<div class="posts">
{{ range .Data.Pages -}}
<article class="post">
  <h1 class="post-title">
    <a href="{{ .Permalink }}">{{ .Title }}</a>
  <time datetime="{{ .Date.Format "2006-01-02T15:04:05Z0700" }}" class="post-date">{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
  {{ .Summary }}
  {{ if .Truncated }}
  <div class="read-more-link">
    <a href="{{ .RelPermalink }}">Read More…</a>
  {{ end }}
{{- end }}
{{- end }}

right from start, I can see it only deals with the main part and not the navigation bar. Makes sense since the nav bar is defined in the partials library and is unchanged. Now I’m trying to get a crack at what I’m looking at here:

{{define "main"}} - this line says, "this whole thing defines what is ‘main’.

<div...> - this is regular HTML, calling for div “posts”. This means we are now defining “posts”.

{{ range .Data.Pages -}} - not sure what this means. Hugo speaks of range being used just as in Go. It is the range of Data.Pages, which are .toml (in my case). I guess it basically calls to use all pages that are .toml on the site. Again, not sure which ones (I think all of them) and it looks generic, leaving this alone.

<article class="post"> - this tells me that now the template is starting to take care of the actual content. Up until now, it was generic definitions and calling different bits from somewhere else. This is where “article” is defined, from this line forward.

Now this is where opening the html from the doc folder (otherwise known as “public” to render the html) is somewhat helpful.

<h1 clas...> ok, this calls the title of the post. This also tells me this is the building block that starts posting my posts on the main page, complete with the link to it. I can guess what .Permalink and .Title do :slight_smile:

<time datetime...> this defines how the timestamp is formatted in Hugo, I saw the part on that (how it’s formatted).

{{.Summary}} The next chunk is a summary of my post, with a conditional that prepares a link of “read it more”. OK.

Next, it’s the end of defining article, and of defining posts.

So here, what I have is the piece that alaready calls the summary of posts and defines them. It looks like what would be a list template. This theory seems to be true because other lists on the theme would look the same.

Looking at all of this, I know I want to create a home template with these general points I’ve learned:

  1. I want to use the baseof template, which calls for the navigation bar at the left, and the content at the right. So, the homepage template should be under baseof in terms of what comes first, because the home page will also have the nav bar that is used throughout the whole site.
  2. I am not sure how the range work here or what it does, but I guess I can leave it alone because I only care for not having summaries of my posts on the first page… however, the main part is a problem. This is because it is defined here, in the homepage template. If I leave it alone, the next list template (which I guess have a “main” part) would simply plant my introdctory text and all with it, because I’m going to put it under. SO, I need to take the main part and put it in the list template which is under defaults, because it’s under homepage in terms of what comes first, and the rest of the site can still use it.
  3. I want to remove the whole <article> bit from my home template. It should, instead, contain text (which I will put in, just introduction) and links inside of that text. Only one link, to my blog, should be pointing somewhere inside hugo (should be pointing to the list templates inside my blog section) and the rest will be outside of this website. Again, the <article> bit needs to be in the list template in default instead.

How does this sound so far…?

Looking at my list.html in _default, I see it too has {{define "main -}}. And so is single.html. So, we do not define it there, it’s something Hugo has built in… I can’t find reference to it or what it does. Maybe that’s because we DO define it, but main is defined differently, depending on which file we’re looking at. This means that baseof calls to two basic things: nav bar and main, where main is defined depending on which part we’re looking at in the website.

homepage has its own main, so does single, so does list.

If that’s true, I do not need to remove the main part from the homepage template. But, how does Hugo knows which “main” to use where? This must be determined by the order of importance, as the documents state. homepage is unique, which means its main is unique, and would not be repeated anywhere else…


See https://gohugo.io/templates/lists/#example-project-directory for example of such range templates.

Your theme is also using the redundant .Data prefix for Pages… {{ range .Pages }} would work the same (the official Hugo docs don’t use that redundant prefix).

Yes, that’s a very good approach… another way is to see the served page in your browser, open the browser inspector (Ctrl + Shift + I) and quickly sift through the HTML code.

Yes, then only list pages (DOMAIN/posts/, etc.) can use the part you moved over there. If you remove index.html from the template, the Homepage will use that same list template too. But since you have index.html, that template can contain stuff unique to only the Homepage (hope that makes sense).

Sounds good… just try it out.

Nothing is built it.

The “placeholder” for “main” is defined in your baseof has {{ block "main" . -}}{{- end }}.

single, list, etc. templates only define what should be inserted in that “main” block… using {{ define "main" }} .. {{ end }}.

In summary, try out things, review more of the themes out there :slight_smile:

Here’s a reference to my “bare min” theme’s layouts/_default/: https://github.com/kaushalmodi/hugo-bare-min-theme/tree/master/layouts/_default. I also use baseof, blocks and defines in there.

Just one more question, which was at the end of what I posted:

Because I saw {{define "main - }} in the four templates (single, list, homepage) I realized that main is indeed defined each time, meaning, each template defines the main environment to what it needs for that template. Then, beucase baseof calls to create a page tha thas main in it, Hugo will use whatever main it being called from template.

So, single page template will use its own version of main, where my homepage will use a different main described there.

I want to know if this makes sense? if so I know I can leave the main part and focus on what’s after.

Yes, each template is defining what “main” should do… and that is done in the place where {{ block "main" }} .. {{ end }} is defined in baseof.

If you know Emacs-Lisp, here’s a crude analogy:

(let ((main ", this is for everything else")) 
  (defun baseof ()
    (message "Hello%s" main)) ;{{ block "main" }}
  ;; single
  (let ((main ", I am in 'single' template")) ;{{ define "main" }} for single
  ;; list
  (let ((main ", I am in 'list' template")) ;{{ define "main" }} for list
  ;; everything else


Hello, I am in 'single' template
Hello, I am in 'list' template
Hello, this is for everything else
1 Like

You nerd! :nerd_face:

1 Like

Emacs Lisp? Ha! I got into Emacs because or Org Mode, and somehow I managed to build my .emacs back together in .org using babel. Don’t ask me how.

I know nothing about programming, this is all just putting 1 and 1 together. Real slow.