title: How do I deploy a static React "app" to Heroku?
body: <p>Title was: <strong>How do I fix "Cannot use import statement outside a module" error on Heroku without causing a "Must use import to load ES Module" error?</strong></p>
  
  <p>This was before I understood that I was trying to deploy a "static" React "app" and Heroku was running index.js as if it was server code.</p>
  
  <p>I had setup <code>Procfile</code> to contain:</p>
  
  <pre><code>web: node ./src/index.js
  </code></pre>
  
  <p>Then I saw this error:</p>
  
  <pre><code>...
  2020-03-29T02:34:01.000000+00:00 app[api]: Build succeeded
  2020-03-29T02:34:02.637867+00:00 heroku[web.1]: State changed from starting to crashed
  2020-03-29T02:34:02.622526+00:00 heroku[web.1]: Process exited with status 1
  2020-03-29T02:34:02.583667+00:00 app[web.1]: /app/src/index.js:1
  2020-03-29T02:34:02.583689+00:00 app[web.1]: import React from 'react';
  2020-03-29T02:34:02.583690+00:00 app[web.1]: ^^^^^^
  2020-03-29T02:34:02.583690+00:00 app[web.1]:
  2020-03-29T02:34:02.583691+00:00 app[web.1]: SyntaxError: Cannot use import statement outside a module
  2020-03-29T02:34:02.583691+00:00 app[web.1]: at wrapSafe (internal/modules/cjs/loader.js:1072:16)
  ...
  </code></pre>
  
  <p>I tried to fix it by adding this to <code>package.json</code>:</p>
  
  <pre><code>  "type": "module",
  </code></pre>
  
  <p>And then I got this error:</p>
  
  <pre><code>...
  2020-03-29T03:05:01.000000+00:00 app[api]: Build succeeded
  2020-03-29T03:05:06.293573+00:00 heroku[web.1]: Starting process with command `node ./src/index.js`
  2020-03-29T03:05:08.744086+00:00 heroku[web.1]: State changed from starting to crashed
  2020-03-29T03:05:08.724957+00:00 heroku[web.1]: Process exited with status 1
  2020-03-29T03:05:08.650103+00:00 app[web.1]: internal/modules/cjs/loader.js:1174
  2020-03-29T03:05:08.650125+00:00 app[web.1]: throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
  2020-03-29T03:05:08.650126+00:00 app[web.1]: ^
  2020-03-29T03:05:08.650126+00:00 app[web.1]:
  2020-03-29T03:05:08.650126+00:00 app[web.1]: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /app/src/index.js
  2020-03-29T03:05:08.650127+00:00 app[web.1]: at Object.Module._extensions..js (internal/modules/cjs/loader.js:1174:13)
  2020-03-29T03:05:08.650127+00:00 app[web.1]: at Module.load (internal/modules/cjs/loader.js:1002:32)
  ...
  </code></pre>
  
  <p>I should've noted that my React "app" is a front-end only that uses a GraphQL API I've already deployed elsewhere. In other words, there is no "server.js that serves [my] react app". (<a href="https://stackoverflow.com/users/1641941/hmr">HMR</a>'s comment led me to that realization. I guess the correct terminology would be to call this a "static app".)</p>
  
  <p>This code in <code>server.js</code> only slightly adapted from <a href="https://stackoverflow.com/users/10053052/tin-nguyen">Tin Nguyen</a>'s answer works:</p>
  
  <pre><code>const http = require('http');
  const path = require('path');
  const express = require('express');
  
  let wss;
  let server;
  const app = express();
  app.use(express.static(path.join(__dirname, './build')));
  
  server = new http.createServer(app);
  
  server.on('error', err =&gt; console.log('Server error:', err));
  server.listen(process.env.PORT);
  </code></pre>
  
  <p>...with this <code>Procfile</code>:</p>
  
  <pre><code>web: node ./server.js
  
  </code></pre>
  
  <p>The only change is the path to the build directory, which I tweaked after snooping around with <code>heroku run bash</code>.</p>
  
  <p>My site isn't working properly, but I think that is the result of my build not being correct. Perhaps that can be solved with a buildpack. But that belongs in a different question. (And I might not bother figuring it out since I plan to take Tin Nguyen's advice and try hosting on GitHub.)</p>
  
  <p><strong>Update</strong>: The problem wasn't with my build, but with client-side routing (as described on <a href="https://create-react-app.dev/docs/deployment/" rel="nofollow noreferrer">https://create-react-app.dev/docs/deployment/</a>). This code (from that page) fixes it (in <code>server.js</code>):</p>
  
  <pre><code>const express = require('express');
  const path = require('path');
  const app = express();
  
  app.use(express.static(path.join(__dirname, 'build')));
  
  app.get('/*', function (req, res) {
    res.sendFile(path.join(__dirname, 'build', 'index.html'));
  });
  
  app.listen(process.env.PORT);
  </code></pre>
  
  <hr>
  
  <p>The <a href="https://daveceddia.com/deploy-react-express-app-heroku/" rel="nofollow noreferrer">link in HMR's comment</a> helped me reach this understanding, but Dave Ceddia writes that his article covers how to keep a React app and API server together. Is there any documentation on how to deploy a front-end on Heroku (or elsewhere) with an API server already deployed elsewhere?</p>
  
  <p>(I found <a href="https://stackoverflow.com/a/56768989/4766">this answer</a> where <a href="https://stackoverflow.com/users/3557386/paras">Paras</a> recommends <a href="https://www.netlify.com/" rel="nofollow noreferrer">Netlify</a>.)</p>