Dynamic routing by sub domain with AngularJS

All we need is an easy explanation of the problem, so here it is.

How do I override template URL based on sub domain?

All of my sub domains point to the same doc root.

Base level domain: example.com

$routeProvider.when('/', {templateUrl: 'views/example.com/home.html'});

Sub-domain: sub.example.com

$routeProvider.when('/', {templateUrl: 'views/sub.example.com/home.html'});

Partials should be indifferent to static / dynamic content. If a controller inside a partial is making service calls for data this interceptor shouldn’t interfere with that.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Easy and clean: I would inspect window.location in the function that sets up your routes, set a variable depending on the subdomain, then use that variable when setting up the routes. As in:

var isSubDomain = window.location.host.indexOf("sub") == 0
var urlPath = isSubDomain ? "sub.example.com" : "example.com";

...

$routeProvider.when('/', {templateUrl: 'views/' + urlPath + '/home.html'});

TL;DR: use JavaScript, not Angular

Method 2

A continuation fo this problem lead to this question, but the answer is applicable for both:

I decided to go with a local stradegy for two reasons:

  1. There is no additional overhead of XML request.
  2. 404 messages wont polute console logs when resource doesn’t exist.

services.js

factory('Views', function($location,$route,$routeParams,objExistsFilter) {

  var viewsService = {};
  var views = {
    subdomain1:{
      'home.html':'/views/subdomain1/home.html'
      },
    subdomain2:{

    },
    'home.html':'/views/home.html',
  };

  viewsService.returnView = function() {
    var y = $route.current.template;
    var x = $location.host().split(".");
    return (x.length>2)?(objExistsFilter(views[x[0]][y]))?views[x[0]][y]:views[y]:views[y];
  };

  viewsService.returnViews = function() {
    return views;
  };

  return viewsService;
}).

controllers.js

controller('AppController', ['$scope','Views', function($scope, Views) {    
  $scope.$on("$routeChangeSuccess",function( $currentRoute, $previousRoute ){
    $scope.page = Views.returnView();
  });
}]).

filters.js

filter('objExists', function () {
  return function (property) {
    try {
      return property;
    } catch (err) {
      return null
    }
  };
});

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply