|
| 1 | +# Using Flex Layout with Server-Side Rendering (SSR) |
| 2 | + |
| 3 | +### Introduction |
| 4 | + |
| 5 | +In the browser, Flex Layout works by utilizing the global `Window` object's |
| 6 | +`MatchMedia` interface. When a breakpoint is activated/deactivated, the service |
| 7 | +informs the Flex directives, which inject CSS styles inline as necessary. |
| 8 | + |
| 9 | +Unfortunately, on the server, we have no access to the `MatchMedia` service, |
| 10 | +and so when the view is rendered for users using SSR, none of the responsive |
| 11 | +breakpoints (i.e. `fxFlex.sm`) are respected. This leads to a mismatch between |
| 12 | +the initial view generated by the server, and the bootstrapped view generated |
| 13 | +by the client. |
| 14 | + |
| 15 | +The solution provided allows Flex Layout to inject static CSS into the head of |
| 16 | +the DOM instead of inline, and taps in to the CSS `@media` breakpoint interface, |
| 17 | +instead of the dynamic JavaScript `MatchMedia` interface. |
| 18 | + |
| 19 | +This guide introduces how to incorporate this functionality into your apps, and |
| 20 | +the limitations to be aware of when using this utility. |
| 21 | + |
| 22 | +### Usage |
| 23 | + |
| 24 | +#### Option 1: Generate static CSS on the server |
| 25 | + |
| 26 | +1. Import the `FlexLayoutServerModule` into the server bundle for your app, |
| 27 | +generally called `app.server.module.ts`: |
| 28 | + |
| 29 | +```typescript |
| 30 | +import {NgModule} from '@angular/core'; |
| 31 | +import {FlexLayoutServerModule} from '@angular/flex-layout/server'; |
| 32 | + |
| 33 | +@NgModule(({ |
| 34 | + imports: [ |
| 35 | + ... other imports here |
| 36 | + FlexLayoutServerModule, |
| 37 | + ] |
| 38 | +})) |
| 39 | +export class AppServerModule {} |
| 40 | +``` |
| 41 | + |
| 42 | +2. That's it! Your app should now be configured to use the server-side |
| 43 | +implementations of the Flex Layout utilities. |
| 44 | + |
| 45 | + |
| 46 | +#### Option 2: Only generate inline styles (legacy option) |
| 47 | + |
| 48 | +1. Simply don't import the `FlexLayoutServerModule`. You'll receive a warning |
| 49 | +on bootstrap, but this won't prevent you from using the library, and the |
| 50 | +warning won't be logged on the client side |
| 51 | + |
| 52 | + |
| 53 | +#### Option 3: Generate no Flex Layout stylings on the server |
| 54 | + |
| 55 | +1. Don't import the `FlexLayoutServerModule` |
| 56 | +2. DO import the `SERVER_TOKEN` and provide it in your app as follows: |
| 57 | + |
| 58 | +```typescript |
| 59 | +import {SERVER_TOKEN} from '@angular/flex-layout'; |
| 60 | + |
| 61 | +{provide: SERVER_TOKEN, useValue: true} |
| 62 | +``` |
| 63 | + |
| 64 | +3. This will tell Flex Layout to not generate server stylings. Please note that |
| 65 | +if you provide this token *and* the `FlexLayoutServerModule`, stylings **will** |
| 66 | +still be rendered |
| 67 | + |
| 68 | +### Limitations |
| 69 | + |
| 70 | +One of the deficiencies of SSR is the lack of a fully-capable DOM rendering |
| 71 | +engine. As such, some functionality of the Flex Layout library is imparied. |
| 72 | +For instance, some Flex directives search for parent nodes with flex stylings |
| 73 | +applied to avoid overwriting styles. However, if those styles are defined in |
| 74 | +a style block, the external component styles, or another stylesheet, Flex Layout |
| 75 | +won't be able to find those styles on the server. |
| 76 | + |
| 77 | +The workaround for this is to **inline all Flex-related styles** as necessary. |
| 78 | +For instance, if in an external stylesheet you have a class that applies |
| 79 | +`flex-direction` to an element, add that styling inline on the element the |
| 80 | +class is applied to. Chances are the impact of this will be minimal, and the |
| 81 | +stylings will be loaded correctly on bootstrap. However, it is an unfortunate |
| 82 | +reality of SSR and the DOM implementation used on the server. |
| 83 | + |
| 84 | +### References |
| 85 | + |
| 86 | +The design doc for this utility can be found |
| 87 | +[here](https://docs.google.com/document/d/1fg04ihw42dJJHGd6fugdiBe39iJot8aErhiE7CjwfmQ) |
0 commit comments