5

how is it possible to bootstrap a component with dynamic NgModule on pageload?

Background: I have a page called by "website.url" or by a subdomain like test.website.url in one app. When a subdomain was called I want to show a landingpage based on it's own NgModule (LpModule). Default module is AppModule.

I've tried to achieve this in main.ts as follows:

import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
    
import {AppModule} from './app/app.module';
import {environment} from './environments/environment';
import {LandingpageModule} from "./app-lp/components/landingpage.module";
    
if (environment.production) {
    enableProdMode();
}
    
const hostname = window.location.hostname;
const secondLevelDomain = hostname.split('.').reverse()[1];
    
// let module = AppModule;
// if(secondLevelDomain && secondLevelDomain !== 'www') {
//     module = LandingpageModule;
// }
    
let module = loadModuleByDomain();
    
platformBrowserDynamic().bootstrapModule(module);
    
function loadModuleByDomain() {
    const hostname = window.location.hostname;
    const secondLevelDomain = hostname.split('.').reverse()[1];
    
    if(secondLevelDomain && secondLevelDomain !== 'www') {
        return LandingpageModule;
    } else {
        return AppModule;
    }
}

It works when ng serve is listening but when I restart ng serve I receive the following error:

Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options. Error: Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.

at Object.resolveEntryModuleFromMain (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@ngtools\webpack\src\entry_resolver.js:128:11)
at AotPlugin._setupOptions (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@ngtools\webpack\src\plugin.js:142:50)
at new AotPlugin (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@ngtools\webpack\src\plugin.js:26:14)
at _createAotPlugin (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\models\webpack-configs\typescript.js:55:12)
at Object.exports.getNonAotConfig (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\models\webpack-configs\typescript.js:70:19)
at NgCliWebpackConfig.buildConfig (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\models\webpack-config.js:27:37)
at Class.run (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\tasks\serve.js:37:98)
at check_port_1.checkPort.then.port (C:\xampp\htdocs\projekte\ontavio\talentstorm\client\node_modules\@angular\cli\commands\serve.js:103:26)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:169:7)

What can I do?

2
  • dynamicmodule or copmonents? Commented Jun 18, 2017 at 15:05
  • Preferably dynamicmodule Commented Jun 19, 2017 at 4:22

1 Answer 1

6

After a long, long search I found a solution today:

https://github.com/angular/angular-cli/issues/2887#issuecomment-281168941

I've created an additional .ts file (main-lp.ts) and added the following code:

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {LandingpageModule} from "./app-lp/components/landingpage.module";
    
export function bootstrapLandingpageModule() {
    platformBrowserDynamic().bootstrapModule(LandingpageModule);
}

In main.ts I've used the following code and it works:

import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
    
import {environment} from './environments/environment';
import {AppModule} from './app/app.module';
import {bootstrapLandingpageModule} from "./main-lp";
    
if (environment.production) {
    enableProdMode();
}
    
if(!isSubDomain()) {
    platformBrowserDynamic().bootstrapModule(AppModule);
} else {
    bootstrapLandingpageModule();
}
    
function isSubDomain() {
    const hostname = window.location.hostname;
    const secondLevelDomain = hostname.split('.').reverse()[1];
    
    return !!(secondLevelDomain && secondLevelDomain !== 'www');
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is really helped me a lot , I was stack on here too. However the only thing I am wondering here is consider today is 2019 Angular 8 is coming out, is this still a best practice to load multiple module or there is some other best practice to follow

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.