Use Nuxt’s build.templates property to contextually generate files

Paul Gascou-Vaillancourt
AX2 Inc.
Published in
3 min readOct 16, 2018

Nuxt offers a number of properties to help you finely control your app’s build process. For example, if you need to customize Babel’s or Webpack’s configuration, enable CSS extraction, or watch for custom files changes , the build property is what you need!

One of these options is the templates property. Templates are widely used in Nuxt modules but also in Nuxt’s core itself and are a useful way of adding files to the app, like plugins or middlewares. The source files are actually lodash templates, which prove extremely useful when passing some options to the templates because it allows you to contextualize the destination file by conditionally rendering or omitting parts of its contents.

Recently, Nuxt’s Discord channel user Ger-Onimo asked the following question:

What’s the best way of rendering a different robots.txt depending on the NODE_ENV of your project?

What he needed was to block crawling (Disallow: /) on his staging environment (NODE_ENV=staging) and to allow it (Allow: /) in production (NODE_ENV=production).

And guess what, build.templates is one possible answer to this question!

The robots.txt file should be placed in the static/ directory of your app because Nuxt serves this directory as is. The catch here is that we won’t be creating static/robots.txt ourselves, we’ll let Nuxt’s builder take care of it by compiling a custom template.

Let’s create a templates/ directory at the project’s root, and a robots.txt file in it. Assuming you’re using Nuxt’s default files structure, your project’s files structure should look like this:

.
├── nuxt.config.js
├── package.json
├── static
│ ├── favicon.ico
└── templates
└── robots.txt

Now let’s create the template by editing templates/robots.txt:

User-agent: *
<% if (options.env === 'staging') { %>Disallow: /<% } %>
<% if (options.env === 'production') { %>Allow: /<% } %>

We’re putting the template’s logic between the <% %> delimiters. As you can see we’re testing an env option. When options.env equals 'staging', the template renders to:

User-agent: *
Disallow: /

And when options.env equals 'production', the template renders to:

User-agent: *Allow: /

Yes, there’s an extra line in there, this is because the first if renders to an empty line since its condition isn’t fulfilled. Feel free to put both conditions on the same line to avoid this.

Now that our template is ready, we must let Nuxt know about it, and make sure it receives the option it needs. Let’s head to nuxt.config.js:

export default {
build: {
templates: [
{
src: './templates/robots.txt',
dst: '../static/robots.txt',
options: {
env: process.env.NODE_ENV
}
}
]
}
}

Here’s what we are doing:

  • We set src to the source file containing our template, this path is relative to the project’s root.
  • We set dst to the destination file, which is static/robots.txt. The path here is relative to the .nuxt directory that is generated at build time, that’s why we need to go up one level by using ../.
  • Finally, we pass the template’s options. Here, we simply set env to the value of NODE_ENV.

And that’s it! You can now build your Nuxt app and robots.txt should be properly generated in the static/ directory:

$ NODE_ENV=staging npx nuxt build # -> Disallow: /
$ npx nuxt build # -> Allow: /

One last thing: make sure you add static/robots.txt to your repo’s ignored files list. The file doesn’t need to be committed since it will be generated as part of your build process:

$ echo "static/robots.txt" >> .gitignore

This is a simple example of what you can do with templates in a Nuxt project, but there’s a lot more you can do with those! Peek around nuxt-community’s modules code to see how developers use them, it might give you some inspiration for your very own templates!

For reference, here’s a repository that showcases the template described in this article: https://github.com/paulgv/contextual-robots-txt

--

--