Skip to content

Transform/Manipulate index html before sending it #926

@Kuirak

Description

@Kuirak

Is there an existing issue that is already proposing this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe it

Expose a function to transform the index.html before sending it to the client to inject some variables or replace certain parts, without setting up a complete view engine setup.

Describe the solution you'd like

It would be great to expose a function transformIndexHtml?: (indexHtml: string)=> string | Promise<string>
With this function any transform can be handled.
Here is the diff file I use to patch-package this feature in our code base:

diff --git a/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts b/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
index a996aff..e1dd974 100644
--- a/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
+++ b/node_modules/@nestjs/serve-static/dist/interfaces/serve-static-options.interface.d.ts
@@ -5,6 +5,7 @@ export interface ServeStaticModuleOptions {
     renderPath?: string | RegExp;
     serveRoot?: string;
     exclude?: string[];
+    transformIndexHtml?: (indexHtml: string) => string;
     serveStaticOptions?: {
         cacheControl?: boolean;
         dotfiles?: string;
diff --git a/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js b/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
index 75c9f9b..d447522 100644
--- a/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
+++ b/node_modules/@nestjs/serve-static/dist/loaders/express.loader.js
@@ -29,7 +29,19 @@ let ExpressLoader = class ExpressLoader extends abstract_loader_1.AbstractLoader
                         const stat = fs.statSync(indexFilePath);
                         options.serveStaticOptions.setHeaders(res, indexFilePath, stat);
                     }
-                    res.sendFile(indexFilePath);
+                    if(options.transformIndexHtml != null) {
+                      fs.readFile(indexFilePath, 'utf8', (err, data) => {
+                        if (err) {
+                            next(err);
+                            return;
+                        }
+                        const transformed = options.transformIndexHtml(data);
+                        res.set('Content-Type', 'text/html');
+                        res.send(transformed);
+                      })
+                    } else {
+                     res.sendFile(indexFilePath);
+                    }
                 }
                 else {
                     next();

Teachability, documentation, adoption, migration strategy

No response

What is the motivation / use case for changing the behavior?

We want to inject a variables into the index.html before sending it to the client. In our case we want to replace the <base href="/"/> with the correct baseUrl in case the application runs on a pathname e.g. http://localhost:3001/app. Additionally we want to set a variable on the window object. We don't want to setup the whole view engine and install something like ejs to do these simple transformations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions