Subsequent sections describe a sample Universal application derived from the Tour of Heroes tutorial
and explain how to build and run that app.
{@a why-do-it}
### Why Universal
There are three main reasons to create a Universal version of your app.
1. Facilitate web crawlers (SEO)
1. Improve performance on mobile and low-powered devices
1. Show the first page quickly
{@a seo}
{@a web-crawlers}
#### Facilitate web crawlers
Google, Bing, Facebook, twitter and other social media sites rely on web crawlers to index your application content and make that content searchable on the web.
These web crawlers may be unable to navigate and index your highly-interactive, Angular application as a human user could do.
Angular Universal can generate a static version of your app that is easy searchable, linkable, and navigable without JavaScript.
It also makes a site preview available since each URL returns a fully-rendered page.
While [AOT](guide/aot-compiler) compilation speeds up application start times, it might not be fast enough for some of your audience, especially users on mobile devices with slow connections.
[53% of mobile site visits are abandoned](https://www.doubleclickbygoogle.com/articles/mobile-speed-matters/) if pages take longer than 3 seconds to load.
With Angular Universal, you can generate landing pages for the app that look like the complete app.
The pages are pure HTML, and can display even if JavaScript is disabled.
The pages do not handle browser events, but they _do_ support navigation through the site using [routerLink](guide/router.html#router-link).
Of course most Angular apps are highly interactive.
The landing page looks real and is far more useful than a "loading" spinner.
But it won't fool anyone for long.
In practice, you'll serve a static version of the landing page to hold the user's attention.
At the same time, you'll load the full Angular app behind it in the manner [explained below](#transition).
The user perceives near-instant performance from the landing page
and gets the full interactive experience after the full app loads.
<divclass="l-sub-section">
Another tool called <ahref="https://universal.angular.io/api/preboot/index.html">Preboot</a> can record browser events such as user keystrokes during the transition and play them back in the full Angular app once it is loaded.
</div>
{@a how-does-it-work}
### How it works
To make a Universal app, you install the `platform-server` package.
The `platform-server` package has server implementations of the DOM, `XMLHttpRequest`, and other low-level features that do not rely on a browser.
You compile the client application with the `platform-server` module instead of the `platform-browser` module.
and run the resulting Universal app on a web server.
The server (a [Node Express](https://expressjs.com/) server in _this_ guide's example)
passes client requests for application pages to Universal's `renderModuleFactory` function.
The `renderModuleFactory` function takes as inputs a *template* HTML page (usually `index.html`),
an Angular *module* containing components,
and a *route* that determines which components to display.
The route comes from the client's request to the server.
Each request results in the appropriate view for the requested route.
The `renderModuleFactory` renders that view within the `<app>` tag of the template, creating a finished HTML page for the client.
Finally, the server returns the rendered page to the client.
### Working around the browser APIs
Because a Universal `platform-server` app doesn't execute in the browser, you may have to work around some of the APIs and capabilities that you otherwise take for granted on the client.
You won't be able reference browser-only native objects such as `window`, `document`, `navigator` or `location`.
If you don't need them on the server-rendered page, side-step them with conditional logic.
Alternatively, look for an injectable Angular abstraction over the object you need such as `Location` or `Document`;
it may substitute adequately for the specific API that you're calling.
If Angular doesn't provide it, you may be able to write your own abstraction that delegates to the browser API while in the browser and to a satisfactory alternative implementation while on the server.
Without mouse or keyboard events, a universal app can't rely on a user clicking a button to show a component.
A universal app should determine what to render based solely on the incoming client request.
This is a good argument for making the app [routeable](guide/router).
Http requests with _relative_ URLs don't work.
You should convert them to _absolute_ URLs on the server which means you'll need to know the server origin.
You can pass the server origin into your app with a [provider](guide/dependency-injection#injector-providers) "universal/*"
as you'll see in the [example below](#http-urls).
Because the user of a server-rendered page can't do much more than click links,
you should [swap in the real client app](#transition) as quickly as possible for a proper interactive experience.
{@a the-example}
## The example
The _Tour of Heroes_ tutorial is the foundation for the Universal sample described in this guide.
The core application files are mostly untouched, with a few exceptions described below.
You'll add more files to support building and serving with Universal.
In this example, Webpack tools compile and bundle the Universal version of the app with the
To make this work, the template for server-side rendering contains the `<script>` tags necessary to load the JavaScript and other asset files for the interactive client app.
Create a `universal/` folder as a sibling to the `app/` folder.
Add to it the following three universal files:
1. The [app server module](#app-server-module)
2. The [Universal engine](#universal-engine)
3. The [web server](#web-server)
{@a app-server-module}
### App server module
The app server module class (conventionally named `AppServerModule`) is an Angular module that wraps the application's root module (`AppModule`) so that Universal can mediate between your application and the server.
`AppServerModule` also tells Angular how to bootstrap your application when running as a Universal app.
Create an `app-server.module.ts` file in the `src/universal` directory with the following `AppServerModule` code:
Your code editor may tell you that this import is incorrect.
It refers to the source file for the `AppServerModule` factory which doesn't exist at design time.
That file _will exist_, briefly, during compilation.
The build process creates it in the `../aot` directory, bundles it with other `universal/` code, and erases it during post-build cleanup. It's never around when you're editing `server.ts`.
All will be well as long as you arrange for the AOT compiler to generate this module factory file _before_ it compiles _this_ web server file.
To ensure that clients can only download the files that they are _permitted_ to see, you will [put all client-facing asset files in the `/dist` folder](#universal-webpack-configuration)
and will only honor requests for files from the `/dist` folder.
If you build a production version of the client app with the CLI's `ng build --prod` command, you do not need a separate universal `index.html`.
The CLI constructs a suitable `index.html` for you. You can skip this subsection and continue to [universal TypeScript configuration](#universal-typescript-configuration).
* Instead you'll load the [production version of the client app](#build-client), `client.js`, which is the result of AOT compilation, minification, and bundling.
That's it for `index-universal.html`.
Next you'll create two universal configuration files, one for TypeScript and one for Webpack.
{@a universal-typescript-configuration}
### Universal TypeScript configuration
Create a `tsconfig.universal.json` file in the project root directory to configure TypeScript and AOT compilation of the universal app.
* The `AotPlugin` runs the AOT compiler (`ngc`) over the prepared TypeScript, guided by the `tsconfig.universal.json` you created [above](#universal-typescript-configuration).
Webpack compiles and bundles the universal app into a single output file, `dist/server.js`, per the [configuration above](#universal-configuration).
It also generates a [source map](https://webpack.js.org/configuration/devtool/), `dist/server.js.map` that correlates the bundle code to the source code.
Source maps are primarily for the browser's [dev tools](https://developers.google.com/web/tools/chrome-devtools/javascript/source-maps), but on the server they help locate compilation errors in your components.
{@a serve}
#### Serve
After building the server bundle, start the server.
<code-exampleformat="."language="bash">
npm run serve:uni
</code-example>
The console window should say
<code-exampleformat="."language="bash">
listening on port 3200...
</code-example>
## Universal in action
Open a browser to http://localhost:3200/.
You should see the familiar Tour of Heroes dashboard page.
Navigation via `routerLinks` works correctly.
You can go from the Dashboard to the Heroes page and back.
You can click on a hero on the Dashboard page to display its Details page.
But clicks, mouse-moves, and keyboard entries are inert.
* Clicking a hero on the Heroes page does nothing.
* You can't add or delete a hero.
* The search box on the Dashboard page is ignored.
* The _back_ and _save_ buttons on the Details page don't work.
User events other than `routerLink` clicks aren't supported.
The user must wait for the full client app to arrive.
The first line shows that the server received a request for '/' and passed it to the Universal engine, which then built the HTML page from your Angular application.
The CLI takes care of the rest, including copying all necessary files to the `/dist` folder.
By default the CLI produces two separate client app bundles, one with the vendor packages (`vendor.bundle.js`) and one with your application code (`inline.bundle.js`).
The **_tsconfig.client.json_** inherits (via `extends`) most settings from the universal `tsconfig`. The _only_ substantive difference is in the `files` section which identifies the client app bootstrapping file, `main.ts`, from which the compiler discovers all other required files.
* The `AotPlugin` references the `./tsconfig.client.json`.
* There's no need to copy asset files because the [universal Webpack config](#universal-webpack-configuration)
took care of them.
* Add the `UglifyJSPlugin` to minify the client app code.
Why minify the client code and not the server code?
You minify client code to reduce the payload transmitted to the browser. The universal server code stays on the server where minification is pointless.
#### Run Webpack for the client
Add an `npm` script to make it easy to build the client from the terminal window.
The transition from the server-rendered app to the client app happens quickly on a development machine.
You can simulate a slower network to see the transition more clearly and
better appreciate the launch-speed advantage of a universal app running on a low powered, poorly connected device.
Open the Chrome Dev Tools and go to the Network tab.
Find the [Network Throttling](https://developers.google.com/web/tools/chrome-devtools/network-performance/reference#throttling) dropdown on the far right of the menu bar.