title: Spring Boot React in separate packages
body: <p>I have a spring boot, java 8 API that I wanted to add a React front end to to make API operations easier to navigate and use. I used <a href="https://www.jhipster.tech/" rel="nofollow noreferrer">JHipster</a> generator to generate a React app. Then I just took the web portion and dropped into my app, however whenever I run the Spring Boot application and try to navigate to port <code>:8080</code> it, I get the following page:</p>
  
  <p><a href="https://i.stack.imgur.com/d8Zbz.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/d8Zbz.png" alt="enter image description here"></a></p>
  
  <p>And the following error in the console:</p>
  
  <pre><code>2019-07-15 15:07:21.414  INFO 29145 --- [)-10.15.114.229] o.a.c.c.C.[.[.[/]                                            : Initializing Spring DispatcherServlet 'dispatcherServlet'
  2019-07-15 15:07:21.414  INFO 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : Initializing Servlet 'dispatcherServlet'
  2019-07-15 15:07:21.414 DEBUG 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : Detected StandardServletMultipartResolver
  2019-07-15 15:07:21.426 DEBUG 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
  2019-07-15 15:07:21.426  INFO 29145 --- [)-10.15.114.229] o.s.w.s.DispatcherServlet                                    : Completed initialization in 12 ms
  2019-07-15 15:07:25.079 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : GET "/", parameters={}
  2019-07-15 15:07:25.093 DEBUG 29145 --- [nio-8080-exec-1] s.d.s.w.PropertySourcedRequestMappingHandlerMapping          : looking up handler for path: /
  2019-07-15 15:07:25.128 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.h.SimpleUrlHandlerMapping                            : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
  2019-07-15 15:07:25.130 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.r.ResourceHttpRequestHandler                         : Resource not found
  2019-07-15 15:07:25.131 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : Completed 404 NOT_FOUND
  2019-07-15 15:07:25.152 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : "ERROR" dispatch for GET "/error", parameters={}
  2019-07-15 15:07:25.153 DEBUG 29145 --- [nio-8080-exec-1] s.d.s.w.PropertySourcedRequestMappingHandlerMapping          : looking up handler for path: /error
  2019-07-15 15:07:25.167 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.m.m.a.RequestMappingHandlerMapping                   : Mapped to public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
  2019-07-15 15:07:25.199 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver                     : Selected 'text/html' given [text/html, text/html;q=0.8]
  2019-07-15 15:07:25.208 DEBUG 29145 --- [nio-8080-exec-1] o.s.w.s.DispatcherServlet                                    : Exiting from "ERROR" dispatch, status 404
  </code></pre>
  
  <p>Here is my project structure:</p>
  
  <pre><code>FooApplication
  ├── build.gradle
  ├── api/
      ├── src.main.java.com.foo/
              ├── FooApplication.java
      └── build.gradle
  ├── web/
      ├── node_modules/
      ├── src.main.webapp/
          ├── app/
              ├── index.tsx
              ├── routes.tsx
              └── app.tsx
          └── index.html
      ├── webpack/
          └── webpack.common.js
      └── build.gradle
  </code></pre>
  
  <p>Here my <code>webpack.common.js</code> file:</p>
  
  <pre><code>const webpack = require('webpack');
  const {BaseHrefWebpackPlugin} = require('base-href-webpack-plugin');
  const CopyWebpackPlugin = require('copy-webpack-plugin');
  const HtmlWebpackPlugin = require('html-webpack-plugin');
  const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
  const path = require('path');
  
  const utils = require('./utils.js');
  
  const getTsLoaderRule = env =&gt; {
    const rules = [
      {
        loader: 'cache-loader',
        options: {
          cacheDirectory: path.resolve('build/cache-loader')
        }
      },
      {
        loader: 'thread-loader',
        options: {
          // There should be 1 cpu for the fork-ts-checker-webpack-plugin.
          // The value may need to be adjusted (e.g. to 1) in some CI environments,
          // as cpus() may report more cores than what are available to the build.
          workers: require('os').cpus().length - 1
        }
      },
      {
        loader: 'ts-loader',
        options: {
          transpileOnly: true,
          happyPackMode: true
        }
      }
    ];
    if (env === 'development') {
      rules.unshift({
        loader: 'react-hot-loader/webpack'
      });
    }
    return rules;
  };
  
  module.exports = options =&gt; ({
    cache: options.env !== 'production',
    resolve: {
      extensions: [
        '.js', '.jsx', '.ts', '.tsx', '.json'
      ],
      modules: ['node_modules'],
      alias: {
        app: utils.root('src/main/webapp/app/')
      }
    },
    module: {
      rules: [
        {
          test: /\.tsx?$/,
          use: getTsLoaderRule(options.env),
          include: [utils.root('./src/main/webapp/app')],
          exclude: [utils.root('node_modules')]
        },
        {
          test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
          loader: 'file-loader',
          options: {
            digest: 'hex',
            hash: 'sha512',
            name: 'content/[hash].[ext]'
          }
        },
        {
          enforce: 'pre',
          test: /\.jsx?$/,
          loader: 'source-map-loader'
        },
        {
          test: /\.tsx?$/,
          enforce: 'pre',
          loader: 'tslint-loader',
          exclude: [utils.root('node_modules')]
        }
      ]
    },
    stats: {
      children: false
    },
    optimization: {
      splitChunks: {
        cacheGroups: {
          commons: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            chunks: 'all'
          }
        }
      }
    },
    plugins: [
      new webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: `'${options.env}'`,
          VERSION: `'${utils.parseVersion()}'`,
          DEBUG_INFO_ENABLED: options.env === 'development',
          // The root URL for API calls, ending with a '/' - for example: `"https://www.jhipster.tech:8081/myservice/"`.
          // If this URL is left empty (""), then it will be relative to the current context.
          // If you use an API server, in `prod` mode, you will need to enable CORS
          // (see the `jhipster.cors` common JHipster property in the `application-*.yml` configurations)
          SERVER_API_URL: `''`
        }
      }),
      new ForkTsCheckerWebpackPlugin({tslint: true}),
      new CopyWebpackPlugin([
        {from: './node_modules/swagger-ui/dist/css', to: 'swagger-ui/dist/css'},
        {from: './node_modules/swagger-ui/dist/lib', to: 'swagger-ui/dist/lib'},
        {from: './node_modules/swagger-ui/dist/swagger-ui.min.js', to: 'swagger-ui/dist/swagger-ui.min.js'},
        {from: './src/main/webapp//swagger-ui/', to: 'swagger-ui'},
        {from: './src/main/webapp/static/', to: 'content'},
        {from: './src/main/webapp/favicon.ico', to: 'favicon.ico'},
        {from: './src/main/webapp/manifest.webapp', to: 'manifest.webapp'},
        // jhipster-needle-add-assets-to-webpack - JHipster will add/remove third-party resources in this array
        {from: './src/main/webapp/robots.txt', to: 'robots.txt'}
      ]),
      new HtmlWebpackPlugin({
        template: './src/main/webapp/index.html',
        chunksSortMode: 'dependency',
        inject: 'body'
      }),
      new BaseHrefWebpackPlugin({baseHref: '/'}),
    ]
  });
  </code></pre>
  
  <p>How do I get spring boot to serve up the <code>index.html</code> file when navigating to <code>localhost:8080</code>? I know I'm going to have to override some default spring boot configurations to get this to work but I'm not clear on what configurations.</p>
  
  <p>I can provide details of any more files upon request, just didn't want to overload the post with unnecessary info.</p>