ionic-team / ionic-cli

The Ionic command-line interface
MIT License
1.99k stars 653 forks source link

Ionic component styles not loading with Angular SSR #5096

Open sureshkumarsendrayan opened 2 hours ago

sureshkumarsendrayan commented 2 hours ago

Description: I'm using Angular 18 standalone application with Ionic 8 and enabled server side rendering. When I try to run SSR, the styles of ionic components are not loading. It just loads the plain html.

Output: image

My ionic info:

Ionic:

   Ionic CLI                     : 7.2.0 (C:\Users\ssendrayan\AppData\Roaming\nvm\v20.15.0\node_modules\@ionic\cli)
   Ionic Framework               : @ionic/angular 8.3.2
   @angular-devkit/build-angular : 18.2.7
   @angular-devkit/schematics    : 18.2.7
   @angular/cli                  : 18.2.7
   @ionic/angular-toolkit        : 12.1.1

Capacitor:

   Capacitor CLI      : 6.1.0
   @capacitor/android : 6.1.2
   @capacitor/core    : 6.1.0
   @capacitor/ios     : 6.1.2

Utility:

   cordova-res : not installed globally
   native-run  : not installed globally

System:

   NodeJS : v20.15.0 (C:\Program Files\nodejs\node.exe)
   npm    : 10.7.0
   OS     : Windows 10
sureshkumarsendrayan commented 2 hours ago

Providing server.ts code below.

`import 'zone.js/node'; import { APP_BASE_HREF } from '@angular/common'; import { CommonEngine } from '@angular/ssr'; import * as express from 'express'; import { existsSync, readdirSync } from 'node:fs'; import { join } from 'node:path'; import bootstrap from './src/main.server';

export function app(): express.Express { const server = express(); const distFolder = join(process.cwd(), 'dist/app/browser'); const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? join(distFolder, 'index.original.html') : join(distFolder, 'index.html');

const commonEngine = new CommonEngine({
    enablePerformanceProfiler: true
});

// Cerca dinamicamente il file CSS generato con hash
const cssFileName = readdirSync(distFolder).find(
    (file) => file.startsWith('styles') && file.endsWith('.css')
);

server.set('view engine', 'html');
server.set('views', distFolder);

// Serve i file statici
server.get(
    '*.*',
    express.static(distFolder, {
        maxAge: '1y'
    })
);

// Gestisce tutte le altre richieste utilizzando l'engine Angular
server.get('*', (req, res, next) => {
    const { protocol, originalUrl, baseUrl, headers } = req;

    commonEngine
        .render({
            bootstrap,
            documentFilePath: indexHtml,
            url: `${protocol}://${headers.host}${originalUrl}`,
            publicPath: distFolder,
            inlineCriticalCss: false,
            providers: [
                { provide: APP_BASE_HREF, useValue: req.baseUrl },
                { provide: 'REQUEST', useValue: req },
                { provide: 'RESPONSE', useValue: res }
            ]
        })
        .then((html) => {
            // Inietta dinamicamente il CSS nel contenuto HTML generato
            if (cssFileName) {
                html = html.replace(
                    '</head>',
                    `<link rel="stylesheet" href="${cssFileName}"></head>`
                );
            }
            res.send(html);
        })
        .catch((err) => next(err));
});

return server;

}

function run(): void { const port = process.env['PORT'] || 4000;

// Avvia il server Node
const server = app();
server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
});

}

declare const non_webpack_require: NodeRequire; const mainModule = non_webpack_require.main; const moduleFilename = (mainModule && mainModule.filename) || ''; if (moduleFilename === __filename || moduleFilename.includes('iisnode')) { run(); }

export default bootstrap; `