1
votes

I have simple html file, that includes css like this:

<link rel="stylesheet" href="./css/style.css" />

I uploaded this html file and css file too google cloud storage, and set permissions to public.

In my application, written in node js, I want to serve this html file when user access my root page.

In my application I have following code:

public async getPublicFile(opts: IGetFileOpts): Promise<File> {
    const bucket = this.storage.bucket(opts.bucket);

    return bucket.file(path.join(opts.type, opts.fileName));
}

@Get()
public async serveFile(@Res() response: Response) {
    const file = await this.storageService.getPublicFile({
        organization: organization,
        fileName: 'index.html',
        type: 'resources',
    });

   file.createReadStream().pipe(response);
}

This works as expected. It will server index.html from bucket. However, since this html file have relative link to css file, it will not load css file since it cannot find it.

How can I fix this, so that also css file will be served? Currently I am running this on local computer, but it will be deployed to Google Compute Engine.

I found this link for AppEngine https://cloud.google.com/appengine/docs/standard/go/serving-static-files

Here in AppEngine I can define some handlers like this:

handlers:
  - url: /favicon\.ico
    static_files: favicon.ico
    upload: favicon\.ico

  - url: /static
    static_dir: public

  - url: /.*
    secure: always
    redirect_http_response_code: 301
    script: auto

but as I understand this will not work on local machine.

Also, how do ecommerce companies solves this issues? For example, every shop can have different theme that can be customizable. So I understand that every tenant has own bucket and in tenant bucket, this customizable theme is saved correct? So how I assume that the should have similar issue like me. How do the cope with this situation and how do the handle it?

1
Actually if you change the documentation link you shared for the Node.js examples, there is a whole section on how to serve files for local development, with a .css example using express.static to apply it, here is the link for the specific section, so it's possible for both production and local development. Of course this is for AppEngine, not Compute Engine, but it's a possible alternative, would this suffice?Rafael Lemos
If your css directory is accessible over http or https you can add a new <base> tag on the server-side while returning response to change the base url of the page. That way the html is served by the app engine and the static assets are pulled from the cloud storage. Read more about base tag here.Prasanth

1 Answers

2
votes

You are currently trying to reach bucket static css file from an index.html served on your google app engine url. This just can't work out of the box.

There are many options to solve this:

  • Serve your index.html from the same bucket in public where are your other static files likes css. This has also the benefit of beeing served as CDN which is more efficient. (this is the way I recommand if possible, the only case you cannot do this might be when you want to compute serverside html things in the index.html file before sending it back to the client, but there are great chances this can be done client side)

  • Build absolute pathes to your css ressources in the index.html "on the fly" or "statically" so the link tag might look like :

<link rel="stylesheet" href="https://bucketurl.com/css/style.css" />
  • Serve all your content with your app programmatically with a special route that will serve static content by reading files from bucket like you do with your index.html. This should let you keep relative pathes for other static files.