ionic-team / ionic-team/ionic-framework
bug: angular, mode always md when doing ssr
- Langage dominant
- TypeScript
- Étoiles
- 52.7k
- Forks
- 13.3k
- Merge moyen
- 1 j 15 h
- PR mergées (30 j)
- 51
Description
# Bug Report
**Ionic version:**
[ ] **4.x**
[x] **5.x**
**Current behavior:**
When using `@ionic/angular-server` the platform mode seems to be hardcoded to `'md'`. It won’t render the specific platform mode inferred from the user agent like it does when using browser rendering.
Also, there’s no way to specify a custom mode for the `IonicServerModule` (something similar to the config option available with `IonicModule.forRoot({...})`)
**Expected behavior:**
Should be able to specify a mode to render the app in the `IonicServerModule`.
**Steps to reproduce:**
**Scenario 1:** No custom config on the `IonicModule.forRoot({...})`
1. Enable (SSR with Angular Universal And Ionic)[https://ionicframework.com/blog/ssr-with-angular-universal-and-ionic/]
2. Run `npm run dev:ssr`
3. Open Chrome dev tools and emulate an iOS device
4. The app doesn't recognize the iOS device and always renders with `'md'` mode
**Scenario 2:** Hardcoding `'ios'` mode on the `IonicModule.forRoot({...})` config
1. Enable (SSR with Angular Universal And Ionic)[https://ionicframework.com/blog/ssr-with-angular-universal-and-ionic/]
2. Run `npm run dev:ssr`
3. Open Chrome dev tools and emulate an iOS device, also disable javascript (in order to properly test SSR)
4. The app doesn't recognize the hardcoded `'ios'` mode and always renders with `'md'` mode
**Note:** In _Scenario 2_ if we enable javascript to allow the transition between SSR and the browser, we first get the app with `'md'` mode and then it transitions to `'ios'` mode. Having an option to config the `mode` in the `IonicServerModule` would avoid this flick.
**Other information:**
I know there are some SSR gotchas to be aware of. There's no way to access the _window_ object or the _navigation user agent_ to detect the correct mode.
**However there are ways to detect the user agent in the server side using for example the request user-agent headers.**
By adding a way to specify the Ionic config through a provider (instead or in addition to the `IonicModule.forRoot({...})`) it would be possible to define the proper mode in SSR.
I'm thinking something like the `APP_INITIALIZER`
#### server.ts (option 1)
We can set a custom header in the response object and get that value in the `app.module.ts` using the `RESPONSE` injection token.
``` typescript
server.get('*', (req, res) => {
// Add custom header to the response we send to our Angular app. We will get this custom header in the AppModule APP_INITIALIZER
res.set('mobile-device', 'ios');
res.render(
indexHtml,
{
req,
res
}
);
});
```
#### server.ts (option 2)
Or we can override a new provider that handles the Ionic config directly in the `server.ts`. For this approach we would need to create a new InjectionToken for the `NEW_IONIC_CONFIG`.
``` typescript
server.get('*', (req, res) => {
res.render(
indexHtml,
{
req,
res,
providers: [
{
provide: NEW_IONIC_CONFIG,
useValue: {
mode: 'ios'
}
}
]
}
);
});
```
#### app.modeule.ts
Then in the `app.module.ts` we can easily get the config from the angular `RESPONSE` injection token or directly from the new `NEW_IONIC_CONFIG` token.
``` typescript
{
provide: APP_INITIALIZER,
useFactory: (platformId: object, response: any) => {
return () => {
// In the server.ts we added a custom response header with information about the device requesting the app
if (isPlatformServer(platformId)) {
if (response && response !== null) {
// Get custom header from the response sent from the server.ts
const mobileDeviceHeader = response.get('mobile-device');
console.log('mobileDeviceHeader', mobileDeviceHeader);
// Set Ionic config mode?
}
} else {
console.log('not server');
}
};
},
deps: [PLATFORM_ID, [new Optional(), RESPONSE]],
multi: true
}
```
**Ionic info:**
```
Ionic:
Ionic CLI : 6.11.8 (/Users/agustin/.npm-global/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 5.3.3
@angular-devkit/build-angular : 0.1001.2
@angular-devkit/schematics : 10.1.2
@angular/cli : 10.1.2
@ionic/angular-toolkit : 2.3.3
Capacitor:
Capacitor CLI : 2.4.1
@capacitor/core : 2.4.1
Utility:
cordova-res (update available: 0.15.1) : 0.11.0
native-run : not installed
System:
NodeJS : v12.14.1 (/usr/local/bin/node)
npm : 6.14.8
OS : macOS Catalina
```
@mhartington I know you have been working with the [`IonicServerModule`](https://github.com/ionic-team/ionic-framework/blob/master/packages/angular-server/src/ionic-server-module.ts). Can you point me in the right direction?
Guide de contribution
Ouvrir le guide de contribution
Évaluation
Cette issue n'a pas encore été évaluée.