3

I developed a site that shows some products from a store. The site URL looks like that:

http://testsite.com

The site has the functionality of sharing the product (it's already working) generating a link that can be shared at facebook or WhatsApp or anywhere. The link of the shared product is:

http://testsite.com/product/1234

Where 1234 is the product ID. All the products have images with the ID name. Ex: 1234.jpg. The link for the image of the product ID 1234 is:

http://testsite.com/static/imgs/1234.jpg

This site is hosted using a simple NGINX server, that just provides the files.

At the head of my index.html file I have a default og:image for sharing:

<meta property="og:image" content="http://testsite.com/static/imgs/main.jpg">

I wanna the NGINX server to replace this default og:image by the shared ID image. I already know how to do that at NGINX. At the NGINX configuration file (/etc/nginx/conf.d/default.conf) I used the sub_filter option. My NGINX configuration file is:

server {
    listen       80;
    server_name *.testsite.com;
    root   /var/www/testsite.com/dist;

    location / {
        try_files $uri $uri/ /index.html;
        index  index.html index.htm;
    }

    location ~ /product/(.*) {
        index  index.html index.htm;

        try_files $uri $uri/ /index.html;

        sub_filter 'http://testsite.com/static/imgs/main.jpg'
        'http://testsite.com/static/imgs/$1.jpg';
        sub_filter_once on;
    }
}

This configuration is working for the location /, but for the location ~ /product/(.*) it is not working.

When I test the sub_fiter option at the location / using any other image it replaces correctly.

QUESTIONS:

1) How can I get the product ID (1234) from the URL (http://testsite.com/product/1234)? $1 is not working.

2) I think that when entering at the location ~ /product/(.*), it also redirects for the location /. How can I fix this configuration file to works as expected?

Derzu
  • 7,011
  • 3
  • 57
  • 60
  • what's your file structure? Do you have /var/www/testsite.com/dist/products/1234/index.html? – Pavel Lint Nov 09 '19 at 10:36
  • @PavelLint the file structure is: /var/www/testsite.com/dist/index.html and /var/www/testsite.com/dist/static/imgs/1234.jpg – Derzu Nov 09 '19 at 12:38

1 Answers1

2

I think your alias statement is the problem. Reading in nginx docs:

location /i/ { alias /data/w3/images/; }

on request of “/i/top.gif”, the file /data/w3/images/top.gif will be sent.

It means that in your case on each ~/product/(.*) request /var/www/testsite.com/dist/index.html will be sent without taking product ID into account. You might want to configure alias on / to avoid that. This is also likely to be the reason you get "redirected" to /.

As for $1, it should work as you have it now. When you fix the alias, I think it will work then. If not, you can try the named match: (?<product>[0-9]+) instead of (.*), then you can use the $product variable to reference the id.

There's another small glitch in your code — you're adding extra quote marks on replace. The second argument to sub_filter is in quotes twice.


Working Example

UPDATE: Ok, I got it working on localhost with the following nginx config (testing on "Hello World"):

        location ~ /product/(\d+)$ {
                set $product $1;
                try_files $uri $uri/ /index.html;
        }

        location / {
                if ( $product = '' ) {
                   set $search 'Non-Existent-String';
                }
                if ( $product != '' ) {
                   set $search 'World'; # the string you want to replace
                }

                index index.html index.htm;
                sub_filter '$search' 'Product #$product';
        }

The key here is that when you use try_files, it does get to location /. So we need to sub_filter in /. We also don't want to sub_filter regular /index.html requests. Something like if ($product) sub_filter would be nice, but is impossible with nginx. So I just leave sub_filter but only set real search string for product requests.

Example

Pavel Lint
  • 3,252
  • 1
  • 18
  • 18
  • what is the correct file you want to render for products? – Pavel Lint Nov 09 '19 at 19:53
  • the product URL is a fake URL is used just for sharing propose. The shared page will be rendered using javascript at the client-side. The NGINX server is supposed to serve just the index.html again. – Derzu Nov 09 '19 at 20:00
  • I updated my question removing alias and the double quotes from the replace (sub_filter) statement. – Derzu Nov 09 '19 at 20:02