On the first hit to a page I want to send a fully rendered page back to the user. This works fine if javascript is disabled, but if javascript is enabled then angular-ui-router looks up the state and renders into ui-view on top of the existing content. Is there a way to disable this on the first page load somehow?
See this issue: https://github.com/angular-ui/ui-router/issues/1807 which suggests using $urlRouterProvider.deferIntercept(), but I can't find much documentation about using it and not sure how to intercept the first page load.
There's two parts: firstly you need to disable the router from kicking in on the first page load. This can be done like so:
app.config(function($httpProvider, $urlRouterProvider) {
// On the first page load disable ui-router so that
// our server rendered page is not reloaded based on the window location.
$urlRouterProvider.deferIntercept();
});
Secondly we need to set up the ui-view correctly: Dumping the server-rendered markup inside the ui-view causes issues weird behaviour with the first controller being run twice (see https://github.com/angular-ui/ui-router/issues/1807), so we'll add our server rendered markup just after the ui-view div and hide the ui-view until there's a navigation event.
<div ng-controller="PropertyDetailCtrl">
<div class="ng-cloak" ng-show="!isFirstPageLoad" ui-view></div>
<div ng-show="isFirstPageLoad">
(server rendered markup goes here)
</div>
</div>
Now we need to set isFirstPageLoad in the $scope:
app.controller('PropertyDetailCtrl', function loader($rootScope, $scope) {
$scope.isFirstPageLoad = true;
$rootScope.$on('$viewContentLoading', function(event, viewConfig) {
$scope.isFirstPageLoad = false;
});
});
We've used ng-cloak to make sure that the page behaves perfectly if javascript is disabled, so now we've got a fully server side rendered first page load with all subsequent navigation handled by ui-router.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With