68

I have an Angular app which runs perfectly in my local and production environment.. After a tiny change I made, I ran the app locally and it works fine.. Then I built the project and copied the dist folder to the web server. The problem is when I try to access to the app I get the following error in the Chrome Inspector:

Uncaught SyntaxError: Unexpected token < inline.1a152b6….bundle.js:1
Uncaught SyntaxError: Unexpected token < polyfills.1553fdd….bundle.js:1
Uncaught SyntaxError: Unexpected token < vendor.94d0113….bundle.js:1
Uncaught SyntaxError: Unexpected token < main.d6f56a1….bundle.js:1

So, it seems like it is a misplaced character but in my local environment the app works fine I don't get any warning or error message on the console..

Gerardo Tarragona
  • 1,185
  • 4
  • 15
  • 28
  • How do you build the app the last time? With the same options? – Vega Jul 20 '17 at 18:27
  • 1
    what does source control diff say – Luke Hutton Jul 20 '17 at 18:28
  • @Vega yep, ng build --prod --aot --deploy-url myApp --base-href myApp – Gerardo Tarragona Jul 20 '17 at 18:32
  • Maybe your server has case sensitivity? Look for name changes in imports, names, etc... As Luke Hutton said, source control diff could be a help – Vega Jul 20 '17 at 18:39
  • If you have an improperly closed tag in the code higher up in the chain, then the first < the interpreter sees after that missing close tag will throw an error as it's still expecting a > on an earlier tag. So the error you're looking for is likely shortly before this point. – Stephen R. Smith Jul 20 '17 at 18:46
  • "After a tiny change I made". what change you made? – Hareesh Jul 20 '17 at 19:21
  • I just added a `routerLink` directive in a html file and maybe some changes in 2 or 3 files but I think those changes are irrelevant. The thing is maybe I add or deleted a character by mistake – Gerardo Tarragona Jul 20 '17 at 19:34
  • I don't know why this is happening but the only thing I did was to clear my browser cache – Niang Moore Aug 05 '18 at 20:21
  • In .NET core this was the only way to solve this issue: https://coderedirect.com/questions/443793/setting-up-angular-deep-linking-on-iis – francisco Mc Manus Dec 30 '21 at 21:26
  • **This solution works like a champ** 1) Index.html file must have tag . Add it in the top of the head section 2) Add URL rewrite in web config file. This file is available under dist folder once you build project using the command given in 3 point below. 3) ng build --prod --base-href ./ 4) Paste dist folder build artifacts to application hosted directory. It should work fine. It is working for me after struggling a lot on internet. – Raghubir Singh May 19 '22 at 12:10
  • **ng build --prod --base-href ./** use this command for production deployment – Raghubir Singh May 19 '22 at 12:16

36 Answers36

43

This is most likely the result of a 404 page or a redirect to a page that serves regular html instead of the expected JavaScript files. (A HTML page starts with <html> or a <!DOCTYPE...>)

Make sure that you have correctly uploaded the files and access the page correctly. You can verify by manually accessing the URL with the browser or look into the network tab of your browser development tools to inspect the response.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Thomas
  • 11,272
  • 2
  • 24
  • 40
  • 2
    If I look into the network tab of my browser I can't see the index.html file.. Yet I still can see the *.js* files, but if I click on any of these files, the index code is showed in the preview tab.. @Thomas – Gerardo Tarragona Jul 21 '17 at 00:52
  • That is exactly what I meant: You have a bad deployment or configuration that serves the index file when a JS file is requested. Assumption is that the deployment did not include the JS files and the index file is served in case a file is not found. – Thomas Jul 21 '17 at 10:39
  • Ok, at least this is getting more sense to me now. But why is it that I can see those files on my *dist* folder and they seem to have their respectively code ?.. – Gerardo Tarragona Jul 21 '17 at 15:15
  • Your local files may be different from what has been copied to your webserver, it could be a caching issue as well. (Try clearing the browser cache) – Thomas Jul 21 '17 at 18:18
  • 5
    I think I just solved it.. I had to modify the script paths and the base href attribute in the index file properly. So, instead of `base href="myApp"`, I changed to `href="/myApp"` and the same thing with the script paths – Gerardo Tarragona Jul 21 '17 at 18:40
  • It looks like the 404, which causes the problem, is a consequence of using FallbackResource /index.html. FallbackResource looked nice but seems not to be able to replace mod_rewrite at the end. – yglodt Jun 20 '19 at 08:35
  • 3
    @GerardoTarragona in my index.html it is already written``. what could be other possible issue? – Sunil Garg Jun 30 '19 at 12:34
  • @Thomas i have this problem on iphone 8 only.why this specific behaviour? – sinan Jan 03 '23 at 06:35
20

I had the same issue:

1) I ran the command

ng build --aot --prod

2) Everything compiled without an error

3) I deleted all the files on the server and copied it all across via FTP(FileZilla) to a windows Azure server

4) Sometimes I get the error

Unexpected token <

and other-times not

Yesterday I noticed that the main[hash].js was missing on the server and that Filezilla did not give me an error copying it.

I then tried copying only that file.It did not work. When I removed the hash part from the filename it copies without a problem.

Work-a-round

Run:

ng  build --aot --prod --output-hashing none

Which works every-time.

So either Filezilla or Windows Server does not allow filenames with a specific length or it does not like certain hashes.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Cobus Swart
  • 217
  • 2
  • 2
9

Got this error as well using angular with express.

I guess when you build an angular project the project is stored in 'dist/the-app' not just 'dist' so this solved my problem on express.

// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist/the-app')));

for me, this error was due to not setting the proper path of the built application.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
shahidfoy
  • 1,951
  • 1
  • 17
  • 23
6

The problem is with the <base href="/"> part of index.html file, it seems angular generates build file inside dist/{yourProjectName}/ but the index.html files goes through the dist/ for build files. Now you have 2 options:

  1. Change the <base href="/"> part of the index.html file to <base href="/dist/{yourProjectName}/"> but now you have inconsistency between the ng serve command and ng build and you can't see your project through ng serve. So you have change that part every time!

  2. The seccond approach that I recommend, is just changing the output path of the project! Go to your angular.json file of your project and change the "outputPath": "dist/{yourProjcetName}", to "outputPath": "dist/" and don't change the base href!

meshkati
  • 1,720
  • 2
  • 16
  • 29
4

I'm totally new to Angular so it may not help or at least seem obvious to a lot of you, but in my case it happened every time I reloaded a page that's not the root page, and it came from the fact that, in my index.html file, the base tag looked like this <base href="./">, I had to remove the . so it looks like this : <base href="/"> .

ZyDucksLover
  • 467
  • 1
  • 7
  • 15
4
<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">

add above lines to index.html

Reason: Chrome caches the index.html so the hash in main.hash.js does not get updated and we get the "unexpected token error <".

  • I added these headers using my .htaccess file. I can see that the headers are received the browser using the inspector. Despite this I still get this error whenever I update the app. I assume this is because the hashes on my .js files change when the app is updated. Can I do nothing about this error? Users see a white page and have to refresh the application. – Dries Nov 30 '21 at 15:16
4

I solved by changing in index.html

<base href="/">

to

<base href=".">

or you can set the exact path to the folder that contains your index.html:

<base href="/path/to/index-folder">
Raschid JFR
  • 580
  • 8
  • 15
3

.NET Core solution if you use SpaStaticFile service collection extension and API project for example.

Base href: /

// ConfigureServices
// Correct RootPath to your angular app build, based on angular.json prop
services.AddSpaStaticFiles(configuration =>
{
    configuration.RootPath = "App/dist";
});

// Configure
// In order to serve files
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
    Path.Combine(Directory.GetCurrentDirectory(), "App", "dist")),
    RequestPath = ""
});
apincik
  • 341
  • 4
  • 14
2

I was facing the same issue.

In my case, the main.bundle.js was missing. Copying that file again to the dist folder solved the issue.

One more change that I did was to change the following in the index.html file in the dist -

<base href=".">

To

<base href="/">
Ninad Kulkarni
  • 474
  • 4
  • 7
2

In my case was a mismatch route path in the server file. the route to statics must be the dir containing both the index.html and the assets dir, not the assets dir itself.

app.use(express.static(path.resolve(__dirname,'/dist')));

app.get('/*', function (req, res) {
  res.sendFile(path.join(path.resolve(__dirname, '/dist/index.html')));
});
Raymond
  • 550
  • 1
  • 5
  • 14
2

I have tried below which is worked for me.

Here

The HTML <base href="xyz"/> specifies a base path for accessing relative URLs to assets such as images, scripts, and style sheets.

For example, given the <base href="/myApp/">, if your app wanted to access css file from the URL such as assets/css/styles.css, it will goes into a server request for myApp/assets/css/styles.css

I have deployed my angular build on Xampp server locally in below two way:

  1. xampp -> htdocs -> "build files" (including assets, .htaccess, index.html, etc.)
  2. xampp -> htdocs -> myApp -> "build files" (including assets, .htaccess, index.html, etc.)

For 1.

Now, I wanted my browser to access localhost:80/assets/css/styles.css, and here our assets folder is in root level, thus for access the css we have to put <base href="./"> which access assets folder from root level.

URL Will goes to : localhost:80/assets/css/styles.css

For 2.

i wanted my browser to access localhost:80/myApp/assets/css/styles.css, so here our assets folder is in root level, thus for access the css we have to put <base href="/myApp/"> which access assets folder from inside the myApp.

URL Will goes to : localhost:80/myApp/assets/css/styles.css

Sandeep Patel
  • 2,069
  • 2
  • 14
  • 20
1

It depends on the server, you are using. For example with Apache, you set the .htaccess file to a relative path on your drive, where your app is located with RewriteBase. Also set the <base href=""> accordingly.

With node, the

app.use(express.static(__dirname + '/dist'));

should go before app.get.

Check also, that the build had no errors and all files were copied to dist.

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
alex351
  • 1,826
  • 1
  • 21
  • 32
1

I have a webapi project and angular, after trying different ways, following resolved the redirection issue for me

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        //For angular url rewriting
        app.Use(async (context, next) =>
        {
            await next();
            if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value))
            {
                context.Request.Path = "/index.html";
                await next();
            }
        })
        .UseDefaultFiles(new DefaultFilesOptions { DefaultFileNames = new List<string> { "index.html" } })
        .UseStaticFiles();

        app.UseAuthentication();

        app.UseMvc();
    }
Aqeel Qureshi
  • 437
  • 1
  • 4
  • 10
1

You can try change the base tag from <base href="/"> to <base href="/project-app/"> inside index.html file.

emrebaris
  • 76
  • 5
1

node server : server.js

const express = require('express');
const app = express();
const path = require('path');
const port = process.env.PORT || 3000;
const pathDeploy = path.join(__dirname, 'dist', 'oursurplus');
app.use(express.static(pth));

app.listen(port, () => {
    console.log(`running on port ${port}`);
});

app.get('/*', (req, res) => {
    res.sendFile(path.join(pathDeploy, 'index.html'));
});

package.json must have the script:

scripts: {
    "build": "ng build --prod --baseHref=\"./\""
}
0

In my experience i'm add other assets to wwwroot is conflicted to detect static base address for asp.net core.

For example:

wwwroot
      |--> assets 
                  |---> ckeditor

Is conflict with angular -> src -> assets and show this error

Uncaught SyntaxError: Unexpected token < inline.1a152b6….bundle.js:1
...
Moslem Shahsavan
  • 1,211
  • 17
  • 19
  • This is because there are two similar assets folders `wwwroot/assets/xxx` & `ClientApp\[Project]\assets` and read from `wwwroot/assets/xxx` Choose another name for the server folder – Moslem Shahsavan Jun 18 '20 at 06:33
0

In my case the <!--...--> was the cause of the error

Sergiu Starciuc
  • 532
  • 5
  • 9
0

I had the same issue, very irritating. I tried several of the solutions found here, but none worked.

Adding the following in the Application Settings blade of the application in the Azure portal did the trick -

App Setting Name: WEBSITE_NODE_DEFAULT_VERSION Value: 6.9.1

> Before and after - excerpts from the deployment log.

remote: The package.json file does not specify node.js engine version constraints.
remote: The node.js application will run with the default node.js version 0.10.40.
remote: Selected npm version 1.4.28


remote: The package.json file does not specify node.js engine version constraints.
remote: The node.js application will run with the default node.js version 6.9.1.
remote: Selected npm version 3.10.8

screen capture from azure portal

Montoo
  • 31
  • 9
0

With a little change in the .htaccess file i managed to fixed this problem.

I changed some lines from https://angular.io/guide/deployment#fallback to the following:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html
daerentis
  • 33
  • 6
0

In my case it was the result of incorrect input of UTF-8 characters.

Syntax was:

<component [inputField]="Artikelns Mått"></component>

First it was solved by just replacing the å with a. But, thats not really a solution.

What solved it was adding '' around the text.

<component [inputField]="'Artikelns Mått'"></component>

Error:

Error: Template parse errors:
Parser Error: Unexpected token 'å' at column 11 in [Artikelns mått] in CadComponent@25:28 ("
    <div class="col-md-4">
        <lte-box>
            <lte-box-header [ERROR ->][headerTitle]="Artikelns mått"></lte-box-header>
            <lte-box-body>
                <table "): CadComponent@25:28
Parser Error: Lexer Error: Unexpected character [å] at column 12 in expression [Artikelns mått] at column 13 in [Artikelns mått] in CadComponent@25:28 ("
    <div class="col-md-4">
        <lte-box>
            <lte-box-header [ERROR ->][headerTitle]="Artikelns mått"></lte-box-header>
            <lte-box-body>
                <table "): CadComponent@25:28
    at SyntaxError.BaseError [as constructor] (webpack:///./@angular/compiler/src/facade/errors.js?:31:27) [<root>]
    at new SyntaxError (webpack:///./@angular/compiler/src/util.js?:163:16) [<root>]
    at TemplateParser.parse (webpack:///./@angular/compiler/src/template_parser/template_parser.js?:170:19) [<root>]
    at JitCompiler._compileTemplate (webpack:///./@angular/compiler/src/jit/compiler.js?:381:68) [<root>]
    at eval (webpack:///./@angular/compiler/src/jit/compiler.js?:264:62) [<root>]
    at Set.forEach (<anonymous>) [<root>]
    at JitCompiler._compileComponents (webpack:///./@angular/compiler/src/jit/compiler.js?:264:19) [<root>]
    at createResult (webpack:///./@angular/compiler/src/jit/compiler.js?:146:19) [<root>]
    at Zone.run (webpack:///./zone.js/dist/zone.js?:112:43) [<root> => <root>]
    at eval (webpack:///./zone.js/dist/zone.js?:534:57) [<root>]
    at Zone.runTask (webpack:///./zone.js/dist/zone.js?:150:47) [<root> => <root>]
    at drainMicroTaskQueue (webpack:///./zone.js/dist/zone.js?:432:35) [<root>]
Joel
  • 5,732
  • 4
  • 37
  • 65
0

I found this to error to be a broad instance of many possible errors. In our application that was using Jhipster generated project, We added google analytics in the index.html. We also tried matomo analytics. Inside the index.html we have script tags as well.

The error was that someone commented out a line of code in our google analytics snippet.

here is an example of the code where the error lived:

<script>
        (function (b, o, i, l, e, r) {
            b.GoogleAnalyticsObject = l;
            b[l] || (b[l] =
                function () {
                    (b[l].q = b[l].q || []).push(arguments)
                });
            b[l].l = +new Date;
            e = o.createElement(i);
            r = o.getElementsByTagName(i)[0];
            e.src = '//www.google-analytics.com/analytics.js';
            r.parentNode.insertBefore(e, r)
        }(window, document, 'script', 'ga'));
        ga('create', '123123'); <! --
        ga('send', 'pageview');
        -->

    </script>

Notice the last three lines where there was <! --. That cause the error for us.

In index.html script tag, to comment out a line we use \\ double back slash. Someone may have attempted to comment this line out using <!-- --> .

This is tricky cause it could have been anywhere.
But its always a good place to start in the index.html

Hope this helps a little.

Gel
  • 2,866
  • 2
  • 18
  • 25
0

I had the same problem and realized that I had changed the app.use(express.static(static folder)) statement after my last deploy causing this same unexpected token < error.

Make sure that your app.use(express.static(static folder)) statement contains the appropriate static folder where your js and css files are located and relative to where you are running node.

If you are using Angular and precompiling (ng build --prod) your front-end Angular code into a dist folder containing these files and not putting your back-end node files in the same folder (e.g a separate backend), then you may need to include the correct path as well.

For my example, I have my precompiled (ng build --prod) Angular files in /dist right off the project directory. Note that I also changed angular.json to be "outputPath": "dist" prior to precompiling to ensure this is where the precompiled Angular code would go. My server.js file that just starts the node server is at the project root, but my app.js file that contains the app.use(express.static(static folder)) statement and all the rest of my back-end node code is in a folder called /backend. The following statements both work for me in this case to correctly find the js and css files and eliminate the unexpected token < error:

  app.use(express.static(path.join('dist')));

or

  app.use(express.static(path.join(__dirname, '../dist')));

Both statements appropriately direct node to look for the static js and css files in the /dist folder.

Michel_T.
  • 2,741
  • 5
  • 21
  • 31
0

Judging by the number of answers, this issue can show up for a host of reasons.

I'll add mine incase it helps others. In my case, I was trying to directly hit a url that I wanted to forward back to index.html and let Angular handle it.

So if I went to http://example.com/some-angular-route/12345

In the network tab, I noticed that it was serving the scripts with the angular route in the url (http://example.com/some-angular-route/runtime.js)

Naturally, since nginx couldn't find /some-angular-route/runtime.js, it fell back to serve to index.html since I set try_files (in the nginx config) to test the $uri first and if couldn't find it, serve index.html. So essentially:

  • index.html has a script tag that tries to load http://example.com/some-angular-route/runtime.js
  • fallback in nginx config serves index.html when it can't resolve the file
  • contents of runtime.js are now same as index.html which starts with <html>
  • Since that isn't valid js, you get Uncaught SyntaxError: Unexpected token <

So how do we get /some-angular-route/ out of the url for runtime.js? We have to make sure you have the base-href set to /. You can do this from the cli with the flag --base-href=/

That flag will add in your head tag of index.html and will force the browser to resolve all scripts from the root of the site. You can be on a url that includes some-angular-route but load a file like runtime.js (which is a relative url) from /.

Matt Jones
  • 74
  • 3
0

After ng build go to dist/your project folder say 'something'. Then open the index.html file and change the base URL, which is by default.

If you put your project folder on nginx or apache then tour base URL should be

<base href="http://localhost/something/">

and in my case, version of Angular is: 7.1.4

Ahmad Sharif
  • 4,141
  • 5
  • 37
  • 49
0

I was facing this issue because I had generated the components but the routing was not proper or had not done with routing, so I think any of you gets this error first of all, check have you left something incomplete.

For me it was because of routing.

syed
  • 606
  • 8
  • 11
0

in your index.ts change

<!--doctype html-->
<!DOCTYPE html>

remember... The <!DOCTYPE> declaration is NOT case sensitive. check the following link

0

the solution for me was: in index.html

<base href="./">
Or Shalmayev
  • 295
  • 1
  • 12
0

I had the same problem cause I had used --base-href and --deploy-url with same parameters. like this:

ng build --base-href /spo/ --deploy-url /spo/ 

When I removed --deploy-url flag everything start to working fine.

Vala Khosravi
  • 2,352
  • 3
  • 22
  • 49
0

In our case, if you are modifying the index.html file deployed in the host server, you must save the encoding of the file to UTF-8 so that it will load the page as is

aj go
  • 637
  • 2
  • 10
  • 27
0

In my case, the HTML was inside the single quotes and it has multiple lines in the template.

so I just provided the HTML inside the backtick character (`) in place of the single quote (')

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
-1

Just add after of / the folder name of you project just like said Gerardo Tarragona.

Example:

/myProject

Regards

-1

For a quick workaround though (WHICH IS DEFINITELY NOT RECOMMENDED AND NOT A GOOD PRACTICE) you can build in non prod mode. Try ng build only.

Avik
  • 739
  • 9
  • 15
  • --prod has now been deprecated. ng build will build in production mode by default. Instead use ng build --configuration development – Carlo Nyte Feb 17 '22 at 13:01
-1

I also had the same problem a couple of times, I solved it this way:

Build the project with a user other than root (ubuntu - normaluser)

root$ chown -R ubuntu:ubuntu my-project-folder/
ubuntu$ cd my-project-folder/
ubuntu$ npm install 
ubuntu$ ng build -xxx params xx etc

In production server show nginx user :

root$ grep -rh user /etc/nginx/*
user www-data; # in my case

Now move or replace my-project-folder

root$ mv my-project-folder/ /var/www/awesome.com

And change permissions to nginx user

root$ chown -R www-data:www-data /var/www/awesome.com

(Y)

Isaac Limón
  • 1,940
  • 18
  • 15
-1

Step 1: Build Project with following command Ref:

ng  build --aot --prod --output-hashing none

Step 2: Add dist folder to code versioning/on server

git add /dist/* -f

Step 3: Checkout build on server and try to refresh page.

Mohammad Zaid Pathan
  • 16,304
  • 7
  • 99
  • 130
-1

For me, the problem cause was permissions of the /assets directory after copying the files genrated in /dist/* to the production machine. The /assets directory was copied over, but upon copying, the permissions on it were being set like this:

drwx------  4 admin admin    4096 Feb 21 08:58 assets/

I needed to chmod -R a+rx assets to get it to look like this:

drwxr-xr-x  4 admin admin    4096 Feb 21 08:58 assets/

And then everything worked perfectly because the web server user could access files in the directory.

The problem here is that (as other people on this question have stated) the problem is really a "file not found" error that's returning a 200 status code. So the browser is requesting a file in /assets, layout-helpers.js in my case, not finding it, and returning the contents of index.html, which the browser then tries to interpret as a JavaScript file, resulting in the contents being returned not being valid JavaScript.

The problem was visible in the web server error logs. It's just be the last I would look for what seems like a JavaScript error, so I wasted a good amount of time looking elsewhere.

Fixing the directory permissions fixed everything.

This was my resolution, hopefully this helps someone else.

Gabriel Magana
  • 4,338
  • 24
  • 23
-3

In my case, I just had to do a 'hard refresh' of the page to clear its cache (using Chrome under Linux it's done by pressing ctrl + F5). After that, everything worked fine again.

Cheers,

Fel
  • 4,428
  • 9
  • 43
  • 94