9

I'm building an angular2 application/widget that will be embedded into TYPO3 as a plugin that can be inserted on any content page. This means it could end up at different root paths e.g.:

/page1/app
/page/subpage/subpage/whatever

The global base url (base href=..) is already set by TYPO3 and can't be changed. How can I give angular some kind of root prefix so that it can build up its routes correctly?

I'm using the new router as documented here: https://angular.io/docs/ts/latest/guide/router.html

jdachtera
  • 709
  • 1
  • 6
  • 10

5 Answers5

16

Actually there is a solution in the angular docs but it's pretty hard to find. It's possible to set the base url in angular without using a <base> tag.
So you just have to set the base url to a global JavaScript variable using fluid and then provide it to angular in the app module.

Fluid:

<script>
   var app_base_url = '<f:uri.page pageUid="{currentPageUid}" />';
</script>

Angular:

declare var app_base_url;

import {Component, NgModule} from '@angular/core';
import {APP_BASE_HREF} from '@angular/common';
@NgModule({
  providers: [{provide: APP_BASE_HREF, useValue:app_base_url}]
})
class AppModule {}

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

Mr Lister
  • 42,557
  • 14
  • 95
  • 136
jdachtera
  • 709
  • 1
  • 6
  • 10
2

I would advice not to use the baseURL config attribute. It is a bit outdated and leads to some problems, like yours.

You can set

config.absRefPrefix = /

All links will be prepended with / now and will also work.

Dimitri L.
  • 3,391
  • 1
  • 11
  • 16
  • Since TYPO3 7.6 it's possible to use `config.absRefPrefix = auto` which is configuring the accordant path automatically. However, this alone does not solve the problem with Angular2 routing. – Oliver Hader Oct 13 '16 at 08:12
  • Thanks, but I don't think that would solve my problem. Also this TYPO3 installation is quite old and I can't change this setup. – jdachtera Oct 20 '16 at 11:06
1

The reason is that your web-server is handling the URL already and thus it's not delegated to the Angular2 routing. To overcome this, you have to use a different LocationStrategy in Angular.

What you're looking for is called HashLocationStrategy to create routes like /page1/app/#/angular-controller/ where /page1/app/ is served from the web-server and /angular-controller/ is the first argument to your Angular2 application logic.

Adjust your module declaration (e.g. app.module.ts)

import {Component, NgModule} from '@angular/core';
import {
  LocationStrategy,
  HashLocationStrategy
} from '@angular/common';
@NgModule({
  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}]
})
class AppModule {}

Find more details in the Angular2 documentation about that (the example was taken from there as well).

Oliver Hader
  • 3,527
  • 16
  • 41
  • The examples are based on Angular 2.0, if you're still on some RC-level, consider upgrading to final first. A lot changed between RC4 and final for instance. – Oliver Hader Oct 12 '16 at 08:54
  • Thanks for your answer, but I really would like to use the "real" urls. Actually I found a solution that works with the default Strategy and will post it here. – jdachtera Oct 20 '16 at 11:05
1

In the latest versions of angular I get an error about the variable, so I use a data-attribute instead

<body data-base-url="whatever/"> ...

Angular:

import {Component, NgModule} from '@angular/core';
import {APP_BASE_HREF} from '@angular/common';
@NgModule({
  providers: [{provide: APP_BASE_HREF, useValue:documnent.body.dataset.baseUrl}]
})
class AppModule {}
Tim Visée
  • 2,594
  • 4
  • 38
  • 47
Steve Maris
  • 784
  • 6
  • 13
0

Look at APP_BASE_HREF in this case, basically in Angular2 and above, you can override the provider like this, this is the example in Angular.io showing this case:

import {Component, NgModule} from '@angular/core';
import {APP_BASE_HREF} from '@angular/common';
@NgModule({
  providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]
})
class AppModule {}

So in that case the APP_BASE_HREF will be replaced by /my/app, so you can do it for each module separately...This just apply within Angular application...

For more info, looking at these pages on Angular doc:

https://angular.io/docs/ts/latest/api/common/index/PathLocationStrategy-class.html

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

Alireza
  • 83,698
  • 19
  • 241
  • 152