Search code examples
reactjsnext.jspug

How to setup the Pug for Next.js?


Almost no search results for "nextjs pug". Google suggests the results for "nuxtjs pug" which is the completely different framework.

One of two relevant search results is this issue. The suggested minimal setup requires too much plugins (I can't understand why I need each of them), too complicated cofigurations and does not work with current versions.

package.json

{
  "devdependencies": {
    "@babel/core": "^7.0.0-beta.51",
    "@babel/plugin-transform-react-jsx": "^7.0.0-beta.51",
    "@babel/plugin-transform-runtime": "^7.0.0-beta.51",
    "@babel/preset-env": "^7.0.0-beta.51",
    "@babel/runtime": "^7.0.0-beta.51",
    "babel-core": "7.0.0-bridge.0",
    "babel-plugin-transform-react-pug": "git://github.com/shirohana/babel-plugin-transform-react-pug.git#dist"
  }
}

.babelrc.js

module.exports = function (api) {
 api.env()
 return {
    presets: [
      ['@babel/env', { useBuiltIns: 'entry' }]
    ],
    plugins: [
      ['babel-plugin-transform-react-pug'],
      ['@babel/plugin-transform-react-jsx'],
      ['@babel/plugin-transform-runtime']
    ]
  }
}

https://github.com/pugjs/babel-plugin-transform-react-pug/pull/48#issuecomment-406466928

Other relevant search result is Is it possible to use Framer Motion in React with pug question. I tried below solution:

{
  "presets": ["next/babel"],
  "plugins": [
    "transform-react-pug",
    [
      "transform-jsx-classname-components"
    ],
    "transform-react-jsx"
  ]
}

It's very interesting, but sometimes in works, sometimes - no. I tried to create two projects. Firstly it works in both projects but then broke with error:

ReferenceError: React is not defined
at HomePage (C:\Users\****\Build\InteractiveImplementation\server\pages\index.js:63:3)
    at processChild (C:\Users\****\node_modules\react-dom\cjs\react-dom-server.node.development.js:3353:14)
    at resolve (C:\Users\****\node_modules\react-dom\cjs\react-dom-server.node.development.js:3270:5)
    at ReactDOMServerRenderer.render (C:\Users\****\node_modules\react-dom\cjs\react-dom-server.node.development.js:3753:22)
    at ReactDOMServerRenderer.read (C:\Users\****\node_modules\react-dom\cjs\react-dom-server.node.development.js:3690:29)
    at renderToString (C:\Users\****\node_modules\react-dom\cjs\react-dom-server.node.development.js:4298:27)
    at Object.renderPage (C:\Users\****\node_modules\next\dist\next-server\server\render.js:53:854)
    at Function.getInitialProps (C:\Users\****\Build\InteractiveImplementation\server\pages\_document.js:556:19)
    at loadGetInitialProps (C:\Users\****\node_modules\next\dist\next-server\lib\utils.js:5:101)
    at renderToHTML (C:\Users\****\node_modules\next\dist\next-server\server\render.js:53:1145)

This error will leave even don't use the Pug:

import React, { ReactNode } from "react";


class TestComponent extends React.Component<TestComponent.Properties,TestComponent.State> {

  public state: TestComponent.State = {
    count: 0
  }

  public render(): ReactNode {
    // return pug`
    //   main
    //     div ${this.props.message}
    //     div props.message
    // `;
    return (
      <div onClick={() => this.increment(1)}>
        {this.props.message} {this.state.count}
      </div>
    )
  }

  private increment(amt: number): void {
    this.setState((state: TestComponent.State): TestComponent.State => ({
      count: state.count + amt,
    }));
  };
}

namespace TestComponent {

  export type Properties = {
    message: string;
  }

  export type State = {
    count: number;
  };
}

export default TestComponent;

You may want to know what I did directly before application broken. Well, I had not record each my of actions, but I had not make some big changes like directories renamig or configuration editing directly before first failed launch. Anyway, we need know where config is wrong and how to fix it.


Solution

  • Try to import this in your pages/index.tsx

    import React from "react";
    

    For Babel transpilation of any jsx code, react import is needed. Import react wherever you use jsx code snippets. This fixes your issue.