Search code examples
expressnginxreverse-proxynuxt.jsfavicon

Nuxtjs Favicons not showing on iOS Safari when bookmarked


I have an issue with Nuxtjs+express using Nginx reverse proxy, that favicons are not showing on iOS Safari when bookmark/favorite only shows the first letter from website title. all my favicons served from static directory and working on safari macOS and all other browsers/platforms, also I have an other app with the same configuration facing the issue.

generally I generate all my favicons using https://realfavicongenerator.net/ and I checked my website and all the results are green. I've tried the following but no luck:-

  1. host favicons on CDN server.
  2. install @nuxt/pwa to generate all the icons.
  3. tried dummy icons from other websites
  4. tested on multiple iOS devices iPad and iPhone cleared the cache, also tried emulators like saucelabs.com
  5. checked nginx access.log and error.log and restart the server
  6. restart PM2
  7. check folder and files permissions
  8. created dummy website on the same server but without Nuxt and everything worked as expected

nuxt.config.js head option

  head: {
   ...
    link: [
      {
        rel: "canonical",
        hid: "canonical",
        href: process.env.APP_URL
      },
      {
        rel: "apple-touch-icon",
        sizes: "180x180",
        href: "/apple-touch-icon.png?v=GvmpJqoA5j"
      },
      {
        rel: "icon",
        type: "image/png",
        sizes: "32x32",
        href: "/favicon-32x32.png?v=GvmpJqoA5j"
      },
      {
        rel: "icon",
        type: "image/png",
        sizes: "192x192",
        href: "/android-chrome-192x192.png?v=GvmpJqoA5j"
      },
      {
        rel: "icon",
        type: "image/png",
        sizes: "16x16",
        href: "/favicon-16x16.png?v=GvmpJqoA5j"
      },
      {
        rel: "manifest",
        href: "/site.webmanifest?v=GvmpJqoA5j"
      },
      {
        rel: "mask-icon",
        href: "/safari-pinned-tab.svg?v=GvmpJqoA5j",
        color: "#611e75"
      },
      {
        rel: "shortcut icon",
        href: "/favicon.ico?v=GvmpJqoA5j",
        type: "image/x-icon"
      },
      {
        rel: "icon",
        href: "/favicon.ico?v=GvmpJqoA5j",
        type: "image/x-icon"
      }
    ],
  ...
  },

nginx

map $sent_http_content_type $expires {
  "text/html"                 epoch;
  "text/html; charset=utf-8"  epoch;
   default                     off; # set this to your needs
}

server {
    listen 80;
    listen [::]:80;
    server_name www.example.com;
    return 301 https://www.example.fm$request_uri;

}


server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    server_name www.example.com;
    rewrite ^/(.*)/$ /$1 permanent;

    gzip            on;
    gzip_types      text/plain application/xml text/css application/javascript;
    gzip_min_length 1000;

    location / {
        expires $expires;
    ########### tried to disable below block
add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
       add_header Referrer-Policy "no-referrer-when-downgrade" always;
       add_header Content-Security-Policy "default-src * data: 'unsafe- 
 eval' 'unsafe-inline'" always;

   # Simple requests
    if ($request_method ~* "(GET|POST)") {
      add_header "Access-Control-Allow-Origin"  *;
    }

    # Preflighted requests
    if ($request_method = OPTIONS ) {
      add_header "Access-Control-Allow-Origin"  *;
      add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";

    add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept,x-key";
      return 200;
    }
    proxy_hide_header X-Powered-By;
        proxy_cache_bypass $http_upgrade;

        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          1m;
        proxy_connect_timeout       1m;
        proxy_pass   http://127.0.0.1:8003;   
    }
}


All favicons are accessible with no issue when go to https://www.example.com/favicon.ico.

any help would be appreciated


Solution

  • Fixed the issue on Safari iOS by adding the below block to nginx config file.

    
      location ~ \.(ico|png|jpg|jpeg|woff) {
            root /var/www/example.com/static;
            add_header Cache-Control 'public, must-revalidate, proxy-revalidate, max-age=31557600';
            access_log off;
            proxy_redirect                      off;
            proxy_set_header Host               $host;
            proxy_set_header X-Real-IP          $remote_addr;
            proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto  $scheme;
    }
    
    

    I don't know what caused the issue in the first place since it's working well on other browsers/platforms, hope it helps someone facing the same issue.