Running Angular2 In Subdirectory
Asked Answered
W

11

33

I have an app which runs fine under localhost.

I tried to put it out on an IIS server today as a child application. So the new path would be localhost/SubDir.

System.js pukes everywhere trying to load modules now. I set the basePath and played with the path/map config variables for a few hours but couldn't land on the magic settings.

Does anyone have ideas what I'd want to tweak, or anything that would help with debugging?

Chrome Console enter image description here

Chrome Network enter image description here

Index HTML

<html>
<head>
    <script src="~/node_modules/es6-shim/es6-shim.js"></script>
    <script src="~/node_modules/systemjs/dist/system.src.js"></script>
    <script src="~/node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="~/node_modules/angular2/bundles/http.dev.js"></script>
    <script src="~/node_modules/angular2/bundles/router.dev.js"></script>

    <link href="~/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->

    <link href="~/assets/css/site.css" rel="stylesheet" />

    <script>
      System.config({
          packages: { 'app': { defaultExtension: 'js' } },
          baseURL: '/MedicheckAngular/',
          paths: {
              //'angular2/*': 'node_modules/angular2/ts/*.js'
          }
      });

      System.import('app/app');
    </script>

</head>
<body>
    <my-app>loading...</my-app>
</body>
</html>

And the App entry point

import {HTTP_PROVIDERS} from 'angular2/http';
import {bootstrap, bind, provide} from 'angular2/angular2';
import {RouteConfig, RouteParams, ROUTER_DIRECTIVES, APP_BASE_HREF, ROUTER_BINDINGS, LocationStrategy, PathLocationStrategy, HashLocationStrategy} from 'angular2/router';

import {AppLayout} from './components/app-layout/app-layout';


bootstrap(AppLayout, [
    ROUTER_BINDINGS,
    HTTP_PROVIDERS,
    provide(APP_BASE_HREF, {useValue:'/'}),
    provide(LocationStrategy, { useClass: HashLocationStrategy })
]);

App Folder Structure

enter image description here

Whittling answered 1/12, 2015 at 1:14 Comment(0)
R
19

To host in a sub directory with apache, you can just do this:

Build command similar to this: ng build --base-href /myapp/

.htaccess file would look like this

RewriteEngine On
RewriteBase /myapp/
Options +FollowSymLinks

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.html [L,QSA]
Ruisdael answered 22/3, 2017 at 9:55 Comment(1)
In my case, Options +FollowSymLinks causes a serve error. Your solution works by removing that line of code. Thank youForefront
K
11

When you're deploying to a non-root path within a domain, you'll need to manually update the following:

<base href="/">

to:

<base href="/MedicheckAngular/">

in your dist/index.html, or make changes as follows:

  1. Change baseUrl: '/MedicheckAngular/' in webpack.common.js.
  2. Add /MedicheckAngular/ to the links in index.html.
Kinross answered 28/5, 2017 at 3:50 Comment(0)
U
6

If you don't know the subdirectory upfront, you can use a dot as path at /src/index.html file like this:

<base href=".">

Then just build with command: ng build --prod. Then get the output from inside of /dist directory as usual.

Now your app can be placed in any web dir or even works from the filesystem (if no restricted API is used).

Unscrew answered 17/10, 2018 at 6:32 Comment(2)
Works for Angular 8. But images are not loading, the src='../assets/images' is 404Devalue
Not sure about previous comment, but this is probably what the devs actually want. I can't think of a reason why any static asset shouldn't be relative.Restaurant
E
4

try to remove the baseURL from the config of systemjs and add the <base href="MedicheckAngular/" /> to your head part in the HTML DOM.

I had my Angular2 App in the subfolders "modules/angular" from the root. `

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hallo</title>
    <base href="modules/angular/">
</head>
<body>
   <myapp>loading...</myapp>

   <script src="/modules/angular/node_modules/es6-shim/es6-shim.min.js"></script>
   <script src="/modules/angular/node_modules/systemjs/dist/system-polyfills.js"></script>
   <script src="/modules/angular/node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
   <script src="/modules/angular/node_modules/angular2/bundles/angular2-polyfills.js">   </script>
   <script src="/modules/angular/node_modules/systemjs/dist/system.src.js"></script>
   <script src="/modules/angular/node_modules/rxjs/bundles/Rx.js"></script>
   <script src="/modules/angular/node_modules/angular2/bundles/angular2.dev.js"></script>

    <script>
    System.config({
        packages: {
            "apps": {
                format: 'register',
                defaultExtension: 'js'
            }
        }
    });
    System.import('apps/main').then(null, console.error.bind(console));
    </script>
</body>
</html>`
Embrangle answered 12/3, 2016 at 15:19 Comment(1)
I tried this but now my url always have the sub folder on it. This does not sound right to me. I need to define the base href as subfolder, but still keep my routing clean without this. Do you think this can be done?Clynes
E
3

I struggled for a while to do something similar. I have a wordpress running on an apache server. For SEO reason we wanted the angular app to be hosted on a sub-folder, in the way phpmyadmin is hosted.

  1. What I did is to create a subfolder in /apps/my-app-hosting-folder
  2. Create an alias to this folder : /my-alias => /apps/my-app-hosting-folder
  3. Change the base ref from base href="/" to base href=""

This worked.

The other things I tried didn't give me satisfaction for the following reasons :

  • set base ref to the alias : I would have needed to manually fix links through the app and with some weird configuration I ended up with something like www.exemple.com/my-alias/my-alias/index; something went wrong between the alias and the base ref.
  • leaving "/" broked some inner link by adding some weird "/" so I had broken url like : www.exemple.com/my-alias/node//blabla; I think it tries to work with the root folder of the server.

Hope it will help the futur readers.

Extender answered 13/9, 2016 at 10:4 Comment(1)
I had my angular(4) app/dist directory sym-linked (steps 1,2). Changing base href="" fixed it. ThanksImmanuel
M
3

I put a ~ on the "base href"

<!-- Angular2 Code -->
<base href="~/">
<link rel="stylesheet" href="styles.css">
<!-- Polyfill(s) for older browsers -->
<script src="~/node_modules/core-js/client/shim.min.js"></script>
<script src="~/node_modules/zone.js/dist/zone.js"></script>
<script src="~/node_modules/reflect-metadata/Reflect.js"></script>
<script src="~/node_modules/systemjs/dist/system.src.js"></script>
<script src="~/systemjs.config.js"></script>
<script>
  System.import('app').catch(function(err){ console.error(err); });
</script>
<!-- Angular2 Code -->
Millisent answered 10/1, 2017 at 20:12 Comment(0)
W
2

Here's what worked for us:

  1. Make the base ref point to the subdirectory containing the angular project. This will ensure that all the node_module dependencies are found, etc.

  2. Configure the PathLocationStrategy with a different APP_BASE_HREF so that html5 mode still works for the actual angular app.

    bootstrap(AppComponent, [..... bind(APP_BASE_HREF).toValue("/yardmap/planning")

ref: https://angular.io/docs/ts/latest/api/common/index/APP_BASE_HREF-let.html

ref: https://angular.io/docs/ts/latest/guide/router.html

Whitsun answered 10/9, 2016 at 19:52 Comment(0)
E
1

Not need to do more , just change one line after the build project in index.html

<base href="/">

to

<base href="/sub directory_name/">

If you want to access route in sub-directory more detail here https://angular.io/guide/deployment#production-servers

Ethel answered 8/10, 2018 at 6:47 Comment(0)
S
0

I think that you've miss a subfolder.

What you've put in your 'index.html' file, means that files to load are located in your home directory.

/home/<your_directory>/[...] <- You try to load files from there.

I think that your server structure is more like that.

/home/<your_directory>/***<app_folder>***/[...] <- I think your files are located here.

If you have a console access to your server , try to locate your application folder, with pwd for example and then replace in your 'index.html' '~/' in your src tags with the returned path and it will work as expected.

Snuff answered 1/12, 2015 at 7:49 Comment(4)
I don't know if I follow what you're suggesting. All the <script> includes from the index.cshtml are pulling in fine with the ~/ paths. Systemjs is having troubles finding the modules thoughWhittling
Could you provide a structure of your working folder ?Snuff
Sure, I've added a screenshot of the app layout to the question.Whittling
I think that the problem is due to the '~' because it means that your file are located under your home directory.Snuff
M
0

The full configuration for running Angular app in subdirectory.

Assuming "ng-app/" as the alias path. For example http://www.example.com/ng-app/

Apache config

Alias /ng-app  /<Directory path of index.html>/
Alias /assets /<Directory path of index.html>/assets/
<Directory /<Directory path of index.html>>
    DirectoryIndex index.html

    Require all granted
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule ^(.*) /index.html [NC,L]
</Directory>

Set baseUrl in index.html

<base href="/ng-app/">

Suppose the angular-app doesn't work on reload, Add the LocationStrategy provider in app.module.ts

import {LocationStrategy, HashLocationStrategy} from '@angular/common';
@NgModule({
    providers: [
        {provide: LocationStrategy, useClass: HashLocationStrategy}
    ]
});
Mclaurin answered 20/4, 2018 at 8:3 Comment(0)
G
0

Dude, in my case what resolved was:

1 - Tip from @SaschaA:

<base href=".">

2 - Reference the files in "./", example:

<link href="./assets/css/site.css" rel="stylesheet" />
<script src="./main.a5555dc5a3ce5f94.js" type="module"></script>

3 - Disable AdBlock enter image description here

Maybe only numbers 2 and 3 will solve it, but that's all I did. Work's for me!

Gallonage answered 10/2 at 11:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.