Generate site content as JSON file without using an output format

The approach encouraged for putting all page content into a JSON file that can be used for user searching is to create a JSON output format for the home page. This does not work in general, since there can be other uses of JSON formats, such as the relatively new JSON feed format. Where search is an optional feature, there’s no way to know whether a “JSON” output format in .AlternateOutputFormats is something the user created for their own purposes like JSON feeds, or whether they enabled the search feature. So when listing alternate formats for a page, say in an RSS or Atom feed, there’s generally no way to know whether a JSON format should be omitted (because it’s a hack special case for the home page), or if it should be included (because it’s for a JSON feed).

Set notAlternative: true for the output format that is not a “alternative”. I use this on many sites where I generate a JSON search index and a JSON feed.

outputFormats:
  SearchIndex:
    mediaType: "application/json"
    baseName: "searchindex"
    isPlainText: true
    notAlternative: true
1 Like

How do you cause the file to be generated? Do you put a home.searchindex.json in the layouts/_default directory?

Yes, exactly. See https://github.com/frjo/hugo-theme-zen/blob/main/layouts/home.searchindex.json

I have in my theme’s hugo.toml:

[outputformats.searchindex]
basename = "searchindex"
isplaintext = true
mediatype = "application/json"
notalternative = true

I have in my theme’s layouts/home.searchindex.json:

{{- $page := . -}}

{{- $page.Scratch.Add "paige_index" slice -}}

{{- range where site.RegularPages "Params.paige.search.hide_page" "ne" true -}}
    {{- $page.Scratch.Add "paige_index" (dict
        "categories" .Params.categories
        "date" .PublishDate
        "description" (.Description | markdownify | plainify | htmlUnescape)
        "keywords" .Params.keywords
        "link" .RelPermalink
        "tags" .Params.tags
        "text" (strings.TrimRight " " (replace (.Plain | htmlUnescape) "\n" " "))
        "title" (.Title | markdownify | plainify | htmlUnescape)) -}}
{{- end -}}

{{- $page.Scratch.Get "paige_index" | jsonify -}}

Yet when I build the exampleSite, I only see public/index.html, no public/index.searchindex.json, no public/index.json, no public/searchindex.json. What am I missing? What would the file be called?

I’ve also tried moving layouts/home.searchindex.json to layouts/_default/home.searchindex.json.

You need to specify outputs. Since search index is global you can add something like this:

outputs:
  home: ["HTML","RSS", "JSON", "SearchIndex"]
  …

Thanks, that got it working! Perfect. :slight_smile:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.