ionic-team / ionic-team/ionic-framework

bug: angular, mode always md when doing ssr

Đang mở
#22,121 2 bình luận 1 reaction 0 người được giao Xem trên GitHub
package: angular type: bug
Ngôn ngữ chính
TypeScript
Star
52.7k
Fork
13.3k
Merge trung bình
1 ngày 15 giờ
Pull request đã merge (30 ngày)
51

Mô tả

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

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.