ionic-team / ionic-team/ionic-framework

bug: angular, mode always md when doing ssr

オープン
#22,121 コメント 2 件 リアクション 1 件 担当者 0 名 GitHub で見る
package: angular type: bug
主要言語
TypeScript
スター
52.7k
フォーク
13.3k
平均マージ
1日 15時間
マージ済み PR(30日)
51

説明

# 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?

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。