Closed Bielik20 closed 3 years ago
Honestly, I don't really understand what you would like to achieve. Could you elaborate, show some examples?
@kamilmysliwiec Take Airbnb for example. If you enter it on desktop you will be served different application than on the mobile. It is not that site is responsive, it is different application.
Youtube is another example. If you pick laptop in chrome responsive devtools, you get whole different application that accessing it with iphone for example. Now, both apps are made responsive, desktop version rearanges content based based od display width. The difference is that mobile app is native like design, it looks like native app, and its also responsive to look good on tables as well as small phones. I did that with my project and it works fine. I use ivy with angular and based on user agent i bootstrap different module dynamically. And on server, also based on user agent i just render different ng factory.
@vladimirdjurdjevic Yes, that is exactly what I have in mind. Would you be able to share a code? It would be great if you could document this use case somehow.
I will share it as soon as i get my hands on laptop. I could impement it here and submit a pull request this weekend if @kamilmysliwiec agrees
Hey @Bielik20. Sorry for the delay. Here is what you can do:
if (device === DeviceType.Mobile) { return import('../app/mobile/mobile.module.browser').then(m => m.MobileModuleBrowser).then(m => platformBrowserDynamic().bootstrapModule(m)); } else { return import('../app/desktop/desktop.module.browser').then(m => m.DesktopModuleBrowser).then(m => platformBrowserDynamic().bootstrapModule(m)); }
For server bundle, you have to build both versions. Just copy paste build setup for server bundle in angular.json, and make it point to different bundle. So you can run something like: ng run app-name:build-server-desktop && ng run app-name:build-server-mobile
Then in your express server code you can import both bundles: const desktopBundle = require('path/to/desktop/bundle'); const mobileBundle = require('path/to/mobile/bundle')
Then you can use mobile-detect package i mentioned to serve appropriate bundle:
`this._expressInstance.get('*', (req, res) => { req.originalUrl = req.path; req.baseUrl = req.path;
const device = new md(req.get('user-agent'));
let ngFactory = null;
let lazyModuleMap = null;
if (device.tablet() || device.mobile()) {
ngFactory = mobileBundle.MobileModuleServerNgFactory;
lazyModuleMap = mobileBundle.LAZY_MODULE_MAP;
} else {
ngFactory = desktopBundle.DesktopModuleServerNgFactory;
lazyModuleMap = desktopBundle.LAZY_MODULE_MAP;
}
res.set('Cache-Control', 'public, max-age=7200, s-maxage=14400');
res.render('index', {
req,
res,
bootstrap: ngFactory,
providers: [
provideModuleMap(lazyModuleMap),
{
provide: REQUEST,
useValue: req
},
{
provide: RESPONSE,
useValue: res
}
]
});
});`
This will effectively render appropriate bundle on the server and provide initial view for the user, and also make sure that browser bootstraps appropriate bundle also with dynamic import. This could be also achieved with the router and lazy loading (also with dynamic import) so you don't have to build separate bundles for server-side. But you have to inject user agent from the server as an additional provider and reset routes based on device. Hope this gives you an idea what needs to be done, I can't share more than this since it's a private project.
Ok, thank you, I needed this last part. Where exactly do you get that this._expressInstance
from?
I have class for my server, and that's just field. You can just call express()
I would have to look more into it how to connect it with nestjs. Thank you.
We don't plan to add more features to this feature as it is supposed to be a tiny wrapper on top of @nguniversal/express-engine
. If anyone needs more functionalities, we recommend forking this package and bringing it to the project's codebase.
I'm submitting a...
Current behavior
No documentation on the subject
Expected behavior
Would love to see an example on how to serve different versions of an application depending on the device/size.
What is the motivation / use case for changing the behavior?
Imagine having an Angular app for the desktop web and an Ionic app for Android/iOS. It would be beneficial to serve the Ionic version on the web to those that enter it on their phones.