Trying to publish the default ASP.NET Core with React app but with Identity.
Here is the MS client app readme

This seems to work without identity by publishing directly from visual studio.
But once identity get's added it get's tricky. With identity, we have an additional wwwroot folder in the publish step.
here is the code for the app I am testing. Here is the MS info I used for the identity and auth. This app signs in locally, and in my user secrects I have set up the
{
"Authentication:Microsoft:ClientId": "IdValue",
"Authentication:Microsoft:ClientSecret": "SecrectValue"
}
Once published it will throw Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 in the console. But again, not on local.
Folder structure of publish without identity
wwwroot
├── ClinetApp
├── build
├── static
├── css
└── js
├── asset-manifest.json
├── favicon.ico
├── index.html
├── manifest.json
├── precache-manifest.<guid>.js
└──service-worker.js
├── appsetting.json
├── appsetting.Development.json
├── MS-DLLs
├── App.dll
├── App.exe
├── App.pdb
├── App.deps.json
├── App.runtimeconfig.json
├── App.Views.dll
├── App.Views.pdb
└── web.config //default web config
For deploying to azure, using this blog post (from ClinetApp/ReadMe), another web config needs to be added into wwwroot in addition to moving the ClinetApp/build folder into wwwroot as well. Much like a normal asp.net core app all the static assets are then put into the wwwroot folder and the dll's moved up to the parent folder.
Deploying with out the second web config gives these errors on the left. Errors on the right are after the second web config gets added into the identity proj.

Web config for identity project that fixes the two console errors
<?xml version="1.0"?>
<configuration>
<system.webServer>
<!--This section is for manifest.json not found error -->
<staticContent>
<mimeMap fileExtension=".woff2" mimeType="application/x-font-woff" />
<mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
<rewrite>
<rules>
<!--This section is for "could not load setting for "App" in AuthorizeService.js" error -->
<rule name="React Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/ (api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Folder structure of publish with identity
├── wwwroot
├── static
├── css
└── js
├── asset-manifest.json
├── favicon.ico
├── index.html
├── manifest.json
├── precache-manifest.<guid>.js
├── //service-worker.js is not used with idenity, see index.html code for explination
└── web.config //used for the routing from blog post
├── appsetting.json
├── appsetting.Development.json
├── MS-DLLs
├── App.dll
├── App.exe
├── App.pdb
├── App.deps.json
├── App.runtimeconfig.json
├── App.Views.dll
├── App.Views.pdb
└── web.config //default web config
Once those issues are fixed from the web config it seems that index.html isn't read correctly. every page request gets Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 when serving the index.html. This is using react-router so one of the suggested fixes was
-app.get('/', function (req, res) {
+app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
but since this is using react router we aren't calling this code in the solution. Below are the App.js, index.js, and index.html
index.js
import 'bootstrap/dist/css/bootstrap.css';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
//import registerServiceWorker from './registerServiceWorker';
const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
const rootElement = document.getElementById('root');
ReactDOM.render(
<Router basename={baseUrl}>
<App />
</Router>,
rootElement);
// Uncomment the line above that imports the registerServiceWorker function
// and the line below to register the generated service worker.
// By default create-react-app includes a service worker to improve the
// performance of the application by caching static assets. This service
// worker can interfere with the Identity UI, so it is
// disabled by default when Identity is being used.
//
//registerServiceWorker();
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<base href="%PUBLIC_URL%/" />
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>CPTest</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
App.js
import React, { Component } from 'react';
import { Route } from 'react-router';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import AuthorizeRoute from './components/api-authorization/AuthorizeRoute';
import ApiAuthorizationRoutes from './components/api-authorization/ApiAuthorizationRoutes';
import { ApplicationPaths } from './components/api-authorization/ApiAuthorizationConstants';
import './custom.css'
export default class App extends Component {
static displayName = App.name;
render () {
return (
<Layout>
<Route exact path='/' component={Home} />
<Route path='/counter' component={Counter} />
<AuthorizeRoute path='/fetch-data' component={FetchData} />
<Route path={ApplicationPaths.ApiAuthorizationPrefix} component={ApiAuthorizationRoutes} />
</Layout>
);
}
}
In Startup.cs these seem to also be breaking the one without identity when trying to add identity to the project.
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
Dev Tools error for index.html not being json
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

So the thing's i've noticed.
- Seems to work all in wwwroot if no identity is used
- Once identity files need to be moved so only static is in wwwroot and the second webconfig
- Still doesn't seem to work because the it is expecting json but getting index.html
- The login page is actually a cshtml page. On localhost, react-router redirects to that page.
_LoginPartial.cshtml
Publish (left) vs Localhost (right) for login page
Publish (left) vs Localhost (right) for counter page (react only)
I have also followed these steps for deploying to prod.
With identity this get's a bit screwy, without it everything works in the azure app service straight from the publish step. Not sure what config needs changed or if anyone has solved this issues another way? Or if something with react router needs to be changed? Any suggestions?

