Integrating React in Hugo

Hi! I am trying to integrate React into Hugo and running into some issues.

Goal:

  • To use React components in Hugo partials and markdown files. We want to replace almost all site parts with react components.

The React library we use is a custom library of components that we wrapped into shortcodes and partials. This seems to be working, but there are a few issues we are facing.

For better clarity, here is how we connected Hugo and React:

React > Hugo connection
To enable passing props from Hugo shortcodes to React component files we use Hugo pipes:

  1. To create a resource from template - we inject the shortcode params as strings into the JS files

const param = {{ .Get "param" }}; // for shortcodes

const param = {{ .Param}}; // for partials

  1. Then, we process JS files with Babel

  2. Then using Webpack we convert all files into the browser-friendly js files

  3. Finally we serve the project using Webpack server (from the “public” folder)

Package.json building script - rimraf public && hugo --debug && webpack && webpack serve

Problem 1: JS files duplication in partials leads to lots of extra building

During the build, Hugo recreates every partial for each page. So if we have a Babel pipeline in it, it can process only one file at a time, so it creates the same file for each page that uses this partial. As the result even with one very small React component in partial - the build time is increasing significantly.

Is there a way to tell Hugo that this file should only be processed once and be shared with the rest of the pages?

Problem 2: There is no hot-reloading

We are only able to see changes after rebuilding the whole website. Is there a way to achieve the same goal but to save hot-reloading?

Problem 3: Shortcodes are not working in partials.

Is there a way to enable this functionality to avoid duplication of shortcodes as partials?

If you have any questions or suggestions - please feel free to ask, correct me or advise solutions! Thank you!

There is no incremental building in Hugo.

No.

Usually it is the other way around. A partial template needs to be defined first so that it can be then called from within a shortcode template that in turn is activated when the shortcode input is used in a Markdown or HTML content file.

I haven’t read your entire post, but I would recommend that you drop webpack and build with js.Build – which has great React support.

Others may point you to some examples.

1 Like

Thank you for your quick response!

I would, but first of all, I can’t modify our React lib, unfortunately, it uses some old fashioned scss imports like “import SomeValues from ‘./scss/variables.scss’;” , and to process such import I must specify “modules: true” in Webpack config - css-loader. JS.Build itself can’t process such files with such import. This is not possible as I am aware. And that’s why we use the Babel pipeline.

Maybe there are some tricks to modify Hugo’s internal js.Build config to enable this option?

After all, if I still will try to render let’s say 200 pages - I have the same issue with unnecessary conversation for each page even with js.Build , am I correct?

Thanks

Thank you for your response!

Are you saying, that what happens now is a “bug” on our side, or that it’s absolutely normal so that many files are being created for each page?

Thanks

When generating a project it gets generated from scratch, you would need some kind of CI so that only changed files are generated.

My comment was in reference to:

Ok. But all I use at the stage we discuss is the command “hugo” to build htmls - how can I change it’s behavior, is that even possible? I do not fully understand how to create this CI and at what moment it should fire. Is there any workaround in Hugo documentation?
Thanks

CI=Continuous Integration service.

Like the one provided by Netlify and similar.

There are several flags for the hugo command.

But it is not possible to build selected files only.
There are no workarounds as far as I know.

You cannot do what you ask without connecting your project with a third party provider to manage incremental deployment.