skip to Main Content

I was deployed my Angular code without Server Side Rendering. It was deployed successfully.
After that I was integrated Server Side Rendering in the project. Now,when Itried to deployed I was showing "You do not have permission to view this directory or page."

[You do not have permission to view this directory or page.](https://i.stack.imgur.com/JHvcr.png)](https://i.stack.imgur.com/JHvcr.png)

[![](https://i.stack.imgur.com/3GfuL.png)](https://i.stack.imgur.com/3GfuL.png)

I have added web.config file
Web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <system.webServer>
      <staticContent>
         <mimeMap fileExtension=".json" mimeType="application/json" />
         <remove fileExtension=".woff" />
         <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
         <mimeMap fileExtension=".woff2" mimeType="font/woff2" />
      </staticContent>
        <rewrite>  
            <rules>  
                <rule name="Angular Routes" stopProcessing="true">  
                    <match url=".*" />  
                    <conditions logicalGrouping="MatchAll">  
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />  
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />  
                    </conditions>  
                    <action type="Rewrite" url="/index.html" />  
                </rule>  
            </rules>  
        </rewrite>  
   </system.webServer>
</configuration>

In server.ts, I am using HOST=0.0.0.0 and PORT=5000. And remaining part is by default by angular SSR
server.ts

import 'zone.js/node';

import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import AppServerModule from './src/main.server';

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
  const server = express();
  const distFolder = join(process.cwd(), 'dist/farmQ/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html'))
    ? join(distFolder, 'index.original.html')
    : join(distFolder, 'index.html');

  const commonEngine = new CommonEngine();

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

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Angular engine
  server.get('*', (req, res, next) => {
    const { protocol, originalUrl, baseUrl, headers } = req;

    commonEngine
      .render({
        bootstrap: AppServerModule,
        documentFilePath: indexHtml,
        url: `${protocol}://${headers.host}${originalUrl}`,
        publicPath: distFolder,
        providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
      })
      .then((html) => res.send(html))
      .catch((err) => next(err));
  });

  return server;
}

function run(): void {
  const port = process.env['SSR_PORT'] || 4000;
  //const PORT = process.env['PORT'] || 5000;
  const PORT = parseInt(process.env['PORT'] || '5000', 10);
  const HOST = '0.0.0.0';

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

  server.listen(PORT, HOST, () => {
    console.log(`Server listening on ${HOST}:${PORT}`);
  });
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
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 AppServerModule;

In my package.json after adding ng add @angular/ssr
"@angular/platform-server": "^17.3.2",
"@angular/ssr": "^17.3.2",
"express": "^4.18.2",
"@types/express": "^4.17.17",
"@types/node": "^18.18.0",
"browser-sync": "^3.0.0",

package.json

{
  "name": "farmQ",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "npm run serve:ssr",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "serve:ssr": "node dist/farmQ/server/main.js --port=5000 --host=0.0.0.0",
    "build:ssr": "ng build && ng run farmQ:server",
    "build:dev:ssr": "ng build --configuration=dev && ng run farmQ:server:dev",
    "build:prod:ssr": "ng build --configuration=production && ng run farmQ:server:production",
    "build:qa:ssr": "ng build --configuration=qa && ng run farmQ:server:qa",
    "build:staging:ssr": "ng build --configuration=staging && ng run farmQ:server:staging",
    "prerender": "ng run farmQ:prerender"  
  },
  "private": true,
  "dependencies": {
    "@ag-grid-community/angular": "^31.0.0",
    "@angular/animations": "^17.3.2",
    "@angular/cdk": "^16.2.14",
    "@angular/common": "^17.3.2",
    "@angular/compiler": "^17.3.2",
    "@angular/core": "^17.3.2",
    "@angular/flex-layout": "^15.0.0-beta.42",
    "@angular/forms": "^17.3.2",
    "@angular/material": "^16.2.14",
    "@angular/platform-browser": "^17.3.2",
    "@angular/platform-browser-dynamic": "^17.3.2",
    "@angular/platform-server": "^17.3.2",
    "@angular/router": "^17.3.2",
    "@angular/ssr": "^17.3.2",
    "@ngx-translate/core": "^14.0.0",
    "@ngx-translate/http-loader": "^7.0.0",
    "ag-grid-angular": "^28.2.1",
    "ag-grid-community": "^28.2.1",
    "angularx-qrcode": "^17.0.0",
    "aws-sdk": "^2.1580.0",
    "bootstrap": "^5.3.3",
    "express": "^4.18.2",
    "font-awesome": "^4.7.0",
    "jquery": "^3.7.1",
    "lodash": "^4.17.21",
    "mock-browser": "^0.92.14",
    "moment": "^2.30.1",
    "ng-material-multilevel-menu": "^6.0.2",
    "ng-otp-input": "^1.9.3",
    "ngx-moment": "^6.0.2",
    "ngx-toastr": "^16.2.0",
    "primeflex": "^3.3.1",
    "primeicons": "^6.0.1",
    "primeng": "^17.12.0",
    "rxjs": "^7.4.0",
    "save": "^2.9.0",
    "sweetalert2": "^11.10.6",
    "tslib": "^2.3.0",
    "xlsx": "^0.18.5",
    "zone.js": "~0.14.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^17.3.2",
    "@angular/cli": "~17.3.2",
    "@angular/compiler-cli": "^17.3.2",
    "@types/express": "^4.17.17",
    "@types/jasmine": "~4.0.0",
    "@types/jquery": "^3.5.29",
    "@types/lodash": "^4.17.0",
    "@types/node": "^18.18.0",
    "@types/qrcode": "^1.5.5",
    "browser-sync": "^3.0.0",
    "jasmine-core": "~4.3.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.0.0",
    "typescript": "~5.4.3"
  }
}

I have given so much time in it, Please provide me some solution for that.

Thank You.

2

Answers


  1. Chosen as BEST ANSWER

    Hi Aslesha Kantamsetti, I tried your solution, I am able to run application browser. But still unable to see Server Side Rendering code, You can see in below image Its only showing

    Here I have used Virtual Path sitewwwrootdist<WebAppName>browser

    I think when SSR is running we can see code inside source code

    enter image description here


  2. I created a simple Angular 17 app with Angular Universal for server-side rendering, and it was successfully deployed to the Azure App Service.

    For Angular Universal, I ran the following command:

    ng add @nguniversal/express-engine
    

    Below is my package.json and server.ts code.

    package.json:

    {
      "name": "my-angular-app",
      "version": "0.0.0",
      "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
        "watch": "ng build --watch --configuration development",
        "test": "ng test",
        "serve:ssr:my-angular-app": "node dist/my-angular-app/server/server.mjs"
      },
      "private": true,
      "dependencies": {
        "@angular/animations": "^17.3.0",
        "@angular/common": "^17.3.0",
        "@angular/compiler": "^17.3.0",
        "@angular/core": "^17.3.4",
        "@angular/forms": "^17.3.0",
        "@angular/platform-browser": "^17.3.0",
        "@angular/platform-browser-dynamic": "^17.3.0",
        "@angular/platform-server": "^17.3.4",
        "@angular/router": "^17.3.0",
        "@angular/ssr": "^17.3.4",
        "@nguniversal/express-engine": "^7.0.2",
        "express": "^4.18.2",
        "rxjs": "^7.8.1",
        "tslib": "^2.6.2",
        "zone.js": "^0.14.4"
      },
      "devDependencies": {
        "@angular-devkit/build-angular": "^17.3.4",
        "@angular/cli": "^17.3.4",
        "@angular/compiler-cli": "^17.3.0",
        "@types/express": "^4.17.17",
        "@types/jasmine": "~5.1.0",
        "@types/node": "^18.18.0",
        "jasmine-core": "~5.1.0",
        "karma": "~6.4.0",
        "karma-chrome-launcher": "~3.2.0",
        "karma-coverage": "~2.2.0",
        "karma-jasmine": "~5.1.0",
        "karma-jasmine-html-reporter": "~2.1.0",
        "typescript": "~5.4.2"
      }
    }
    

    server.ts:

    import { APP_BASE_HREF } from '@angular/common';
    import { CommonEngine } from '@angular/ssr';
    import express from 'express';
    import { fileURLToPath } from 'node:url';
    import { dirname, join, resolve } from 'node:path';
    import bootstrap from './src/main.server';
    export function app(): express.Express {
      const server = express();
      const serverDistFolder = dirname(fileURLToPath(import.meta.url));
      const browserDistFolder = resolve(serverDistFolder, '../browser');
      const indexHtml = join(serverDistFolder, 'index.server.html');
      const commonEngine = new CommonEngine();
      server.set('view engine', 'html');
      server.set('views', browserDistFolder);
      server.get('*.*', express.static(browserDistFolder, {
        maxAge: '1y'
      }));
       server.get('*', (req, res, next) => {
        const { protocol, originalUrl, baseUrl, headers } = req;
        commonEngine
          .render({
            bootstrap,
            documentFilePath: indexHtml,
            url: `${protocol}://${headers.host}${originalUrl}`,
            publicPath: browserDistFolder,
            providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
          })
          .then((html) => res.send(html))
          .catch((err) => next(err));
      });
      return server;
    }
    function run(): void {
      const port = process.env['PORT'] || 5000;
      const server = app();
      server.listen(port, () => {
        console.log(`Node Express server listening on http://localhost:${port}`);
      });
    }
    run();
    

    If you want to add a port, you can add it to the server.ts file.

    I deployed the Angular App to Azure using VS Code, and it was successful, as shown below.

    enter image description here

    If you are deploying to the Azure Linux web, add this startup command:

    pm2 serve /home/site/wwwroot/dist/<WebAppName>/browser --no-daemon --spa
    

    as shown below.

    enter image description here

    If you are deploying it to the Azure Windows app Add the path in Configuration-> Path Mapping -> Virtual Path

    sitewwwrootdist<WebAppName>browser
    

    as shown in below.

    enter image description here

    Output:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search