How to add a favicon to a Next.js static site? - favicon

I'm trying to add a favicon to a Next.js static site without much luck.
I've tried customising the document with components from 'next/document'
https://nextjs.org/docs/#custom-document
A straight link to the favicon.ico file doesn't work because the file isn't included in the build and the href doesn't update to /_next/static/...
Importing the image and adding to the link's href doesn't work either (see commented out lines).
import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
// import favicon from '../data/imageExports';
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html>
<Head>
{/* <link rel="shortcut icon" href={favicon} /> */}
<link rel="shortcut icon" href="../images/icons/favicon.ico" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
The favicon links get added however it doesn't display. I'd expect it to work when I import the file, but it just adds a <link rel="shortcut icon" href="[object Object]"> link.
Has anyone done this yet?

Create a /static folder in project root. This will be added to the static export folder.
Add favicon file in /static folder.
Add _document.js to /pages/ folder according to documentation (nextjs.org) or documentation (github.com).
Add <link rel="shortcut icon" href="/static/favicon.ico" /> to head.
npm run build && npm run export
P.S. Thanks to the previous answer that was deleted. It works!
Edit: Another way is to do this is to import Head into your root layout and add the link there. Anything added to Head gets inserted into the document head tag.
import Head from 'next/head';
const Page = (props) => (
<div>
<Head>
<link rel="shortcut icon" href="/static/favicon.ico" />
</Head>
// Other layout/components
</div>
);
export default Page;
Update :
The static directory has been deprecated in favor of the public directory. Doc
So, the code would now look like
import Head from 'next/head';
const Page = (props) => (
<div>
<Head>
<link rel="shortcut icon" href="/favicon.ico" />
</Head>
// Other layout/components
</div>
);

Simply add your favicon.ico in public folder,
Next js will automatically take that favicon for all pages.
No need to add any favicon link to any pages or in tag no need to add link for favicon.
https://github.com/zeit/next.js/blob/master/errors/static-dir-deprecated.md

The accepted answer is nice, but might be worth pointing out that you don't have to modify _document.js for adding a favicon (nor for adding any tags to head).
I found out for myself that placing favicon in _app.js makes more sense. This file is most likely to exist already for setting up a layout for the pages or something like this. And you can add Head tag literally anywhere (see the docs)
So I ended up with _app.js
class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
return (
<Layout>
<Head>
<link rel="shortcut icon" href="/favicon.ico" />
</Head>
<Component {...pageProps} />
</Layout>
);
}
}

As of June 2020, you don't have to add/edit the document.js or _head.js files. All you need do to is place the favicon.ico file inside the public directory and that's it.

Only adding .ico file is not enough.
Add link tags to <Head> section in _document.jsx or _document.tsx The question is only about .ico file, but I would recommend to add different dimensions and formats for better support.
import React from 'react';
import Document, { Html, Head, Main, NextScript, DocumentContext, DocumentInitialProps } from 'next/document';
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render(): React.ReactElement {
return (
<Html>
<Head>
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
<link rel="manifest" href="/favicons/site.webmanifest" />
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#ffc40d" />
<meta name="theme-color" content="#ffffff" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
You can generate different icons using RealFaviconGenerator and upload results to /public/favicons/ folder. This folder can be referenced by /favicons/ due to nature of public directory.

In my case it DID NOT WORK WITH OUT THE IMPORT:
file: _app.tsx
import { AppContext, AppProps } from "next/app";
import "../styles/common.scss";
import Head from 'next/head';
//For me it didn't work without the following import...
import favico from "../static/favicon.ico";
function MyApp({ Component, pageProps }: AppProps) {
const csrfToken = pageProps["anti-csrftoken-a2z"];
return (
<div>
<Head>
<link rel="shortcut icon" href={favico} type="image/x-icon" />
</Head>
<Component {...pageProps} />
</div>
);
}
MyApp.getInitialProps = async ({ Component, ctx }: AppContext) => {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
};
export default MyApp;

I had to do favicon.src to make it work
Doesn't work:
import favicon from '...'
...
<link rel="shortcut icon" href={favicon} />
Works:
import favicon from '...'
...
<link rel="shortcut icon" href={favicon.src} />
To figure this out, I ran console.log(favicon) and it turns out that it was an object that looks something like this:
{
height: 16,
src: "path/to/favicon.603d046c.ico"
width: 16,
}

Next.js can serve static files, like images, under a folder called
public in the root directory. Files inside public can then be
referenced by your code starting from the base URL (/).
For example, if you add an image to public/me.png, the following code
will access the image:
import Image from 'next/image'
function Avatar() {
return <Image src="/me.png" alt="me" width="64" height="64" />
}
export default Avatar
Note: next/image requires Next.js 10 or later.
This folder is also useful for robots.txt, favicon.ico, Google
Site Verification, and any other static files (including .html)!
For your case, if you just replace the favicon.ico it will update accordingly.
For more details visit the official documentation.

I think it would be useful for someone
<Head>
<link rel="apple-touch-icon" sizes="57x57" href="/favicons/apple-touch-icon-57x57.png" />
<link rel="apple-touch-icon" sizes="60x60" href="/favicons/apple-touch-icon-60x60.png" />
<link rel="apple-touch-icon" sizes="72x72" href="/favicons/apple-touch-icon-72x72.png" />
<link rel="apple-touch-icon" sizes="76x76" href="/favicons/apple-touch-icon-76x76.png" />
<link rel="apple-touch-icon" sizes="114x114" href="/favicons/apple-touch-icon-114x114.png" />
<link rel="apple-touch-icon" sizes="120x120" href="/favicons/apple-touch-icon-120x120.png" />
<link rel="apple-touch-icon" sizes="144x144" href="/favicons/apple-touch-icon-144x144.png" />
<link rel="apple-touch-icon" sizes="152x152" href="/favicons/apple-touch-icon-152x152.png" />
<link rel="apple-touch-icon" sizes="167x167" href="/favicons/apple-touch-icon-167x167.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon-180x180.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="96x96" href="/favicons/favicon-96x96.png" />
<link rel="icon" type="image/png" sizes="128x128" href="/favicons/favicon-128x128.png" />
<link rel="icon" type="image/png" sizes="196x196" href="/favicons/favicon-196x196.png" />
<link rel="icon" type="image/png" sizes="192x192" href="/favicons/android-chrome-192x192.png" />
<link rel="icon" type="image/png" sizes="512x512" href="/favicons/android-chrome-512x512.png" />
<link rel="shortcut icon" href="/favicons/favicon.ico" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="msapplication-TileImage" content="/favicons/mstile-144x144.png"/>
<meta name="msapplication-square70x70logo" content="/favicons/mstile-70x70.png"/>
<meta name="msapplication-square150x150logo" content="/favicons/mstile-150x150.png"/>
<meta name="msapplication-square144x144logo" content="/favicons/mstile-144x144.png"/>
<meta name="msapplication-square310x310logo" content="/favicons/mstile-310x310.png"/>
</Head>

For me it was missing in production site but working fine in local because I didn't add the public folder in the artifacts of the production site. I assumed that next.js would put all it needs in .next folder but it's not the case.
cp -R ./.next/ artifacts/
cp -R ./node_modules/ artifacts
cp -R ./public/ artifacts #missing line in my github action code
cp package.json ./artifacts/package.json

I had to put mine under public/images directory with Next.js v18.
Putting under public did not work.

Related

Flutter web get loading error after deployed on Jenkins

When deploying to Jenkins and then accessing the website, it was just loading.
Chrome console:
"Refused to execute script from 'https://******.com/web_entrypoint.dart.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled."
-"Uncaught Error: Script error for "web_entrypoint.dart", needed by: main_module.bootstrap".
This is code index.html
/
<!DOCTYPE html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="taskdino_platform">
<link rel="apple-touch-icon" href="icons/ic_launcher.png">
<!-- Croppie -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.5/croppie.css" />
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.3.0/exif.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.5/croppie.min.js"></script>
<!-- Favicon -->
<link rel="icon" type="image/png" href="ic_launcher.png"/>
<title>Taskdino</title>
<link rel="manifest" href="manifest.json">
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAAmDUD2ziWCN5Q1uIbk7fRKnJQWpRQqeE"></script>
<script>
// The value below is injected by flutter build, do not touch.
var serviceWorkerVersion = null;
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
</head>
<body>
<div id="loading"></div>
<script>
window.addEventListener('load', function(ev) {
var loading = document.querySelector('#loading');
loading.textContent = "Loading entrypoint...";
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
}
}).then(function(engineInitializer) {
loading.textContent = "Initializing engine...";
return engineInitializer.initializeEngine();
}).then(function(appRunner) {
loading.textContent = "Running app...";
return appRunner.runApp();
});
});
</script>
</body>
</html>
/*
Please help!
Much obliged.

Sweetalert 2 i cant make this library work

Here is the problem. Sorry for stupid question.
I read how to connect this library to my project.
I use vs-code. First, i need to install npm in my project with command npm install sweetalert2 in vs-code terminal. I did that.
Next i need to add reference to sweetalert2.min.js and sweetalert2.min.css in <head>.
And call the function.
Swal.fire({
title: 'Error!',
text: 'Do you want to continue',
icon: 'error',
confirmButtonText: 'Cool'
})
I also make button with onclick function but this not work. I click button and nothing. No modal window.
Here is my code. Help to see my problem. Thank you!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="styles/style.css" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Oleo+Script+Swash+Caps&display=swap" rel="stylesheet">
<script src="/node_modules/sweetalert2/dist/sweetalert2.min.js"></script>
<link rel="stylesheet" href="/node_modules/sweetalert2/dist/sweetalert2.min.css">
<script>
function CBR_XML_Daily_Ru(rates) {
function trend(current, previous) {
if (current > previous) return ' ▲';
if (current < previous) return ' ▼';
return '';
}
var USDrate = rates.Valute.USD.Value.toFixed(4).replace('.', ',');
var USD = document.getElementById('USD');
USD.innerHTML = USD.innerHTML.replace('00,0000', USDrate);
USD.innerHTML += trend(rates.Valute.USD.Value, rates.Valute.USD.Previous);
var EURrate = rates.Valute.EUR.Value.toFixed(4).replace('.', ',');
var EUR = document.getElementById('EUR');
EUR.innerHTML = EUR.innerHTML.replace('00,0000', EURrate);
EUR.innerHTML += trend(rates.Valute.EUR.Value, rates.Valute.EUR.Previous);
}
</script>
<link rel="dns-prefetch" href="https://www.cbr-xml-daily.ru/">
<script src="https://www.cbr-xml-daily.ru/daily_jsonp.js" async></script>
</head>
<body>
<button onclick="functi()">Тест Sweetalert</button>
<div class="container-message">
<div class="mainInfo">
<h1>Что день грядующий нам готовит ? Богатство или бедность? <span class="usd-color">&#36</span></h1>
<div id="USD">Доллар США $ — 00,0000 руб.</div>
<div id="EUR">Евро € — 00,0000 руб.</div>
</div>
</div>
<script>
function functi() {
Swal.fire({
title: 'Error!',
text: 'Do you want to continue',
icon: 'error',
confirmButtonText: 'Cool'
})
}
</script>
</body>
</html>
And also attach chrome-console log console
So, i find solution.
I use cdn url from documentation <script src="//cdn.jsdelivr.net/npm/sweetalert2#11"></script>.
But this not work.
I change this url in head to <script src="https://cdn.jsdelivr.net/npm/sweetalert2#11"></script>
And it works!

Unable to use require in VSCode extension renderer process

I am trying to use import in the script I loaded in HTML, but the error occurs:
Uncaught ReferenceError: require is not defined.
I am trying to order my code with classes in typescript. Does that mean everything I write for the renderer process in vscode extensions has to be in one js file?
New to extension programming, any help appreciated.
Here is how I build HTML:
webviewPanel.webview.html = getHtmlTemplate(webviewPanel, this.context);
and my HTML looks like:
export function getHtmlTemplate(webviewPanel: vscode.WebviewPanel, context: vscode.ExtensionContext) : string {
const scriptUri = webviewPanel.webview.asWebviewUri(vscode.Uri.joinPath(
context.extensionUri, 'out', 'main.js'));
const styleResetUri = webviewPanel.webview.asWebviewUri(vscode.Uri.joinPath(
context.extensionUri, 'media', 'reset.css'));
const styleVSCodeUri = webviewPanel.webview.asWebviewUri(vscode.Uri.joinPath(
context.extensionUri, 'media', 'vscode.css'));
const styleMainUri = webviewPanel.webview.asWebviewUri(vscode.Uri.joinPath(
context.extensionUri, 'media', 'style.css'));
// Use a nonce to whitelist which scripts can be run
const nonce = getNonce();
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src ${webviewPanel.webview.cspSource}; style-src ${webviewPanel.webview.cspSource}; script-src 'nonce-${nonce}';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet" />
<link href="${styleVSCodeUri}" rel="stylesheet" />
<link href="${styleMainUri}" rel="stylesheet" />
<title>Cat Scratch</title>
</head>
<body>
<div class="container">
<div class="split left">
<h1>Story Editor</h1>
</div>
<div class="split right">
<h1>Story Blueprint</h1>
<div class="nodes">
<div class="add-button">
<button>Create Node</button>
</div>
</div>
<canvas id = "_canvas"></canvas>
</div>
</div>
<script nonce="${nonce}"> var exports = {}; </script>
<script nonce="${nonce}" src="${scriptUri}"></script>
</body>
</html>`;
}
I am writing main.ts which will be compile into main.js, and I would like to use import in main.ts

ionic lost permission afer close app(pwa)

Please, if anyone knows how to solve that..
I made a pwa with ionic and onesignal..evething is fine until i close the pwa...
After that onesignal lost the permission to notification and you have to give the permision again
next the code.
INDEX.HTML
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Ionic App</title>
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<link rel="icon" type="image/x-icon" href="assets/icon/favicon.ico">
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#4e8ef7">
<!-- add to homescreen for ios -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<!-- cordova.js required for cordova apps (remove if not needed) -->
<script src="cordova.js"></script>
<!-- un-comment this code to enable service worker -->
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.error('Error', err));
}
</script>
<link href="build/main.css" rel="stylesheet">
</head>
<body>
<!-- Ionic's root component and where the app will load -->
<ion-app></ion-app>
<!-- The polyfills js is generated during the build process -->
<script src="build/polyfills.js"></script>
<!-- The vendor js is generated during the build process
It contains all of the dependencies in node_modules -->
<script src="build/vendor.js"></script>
<!-- The main bundle js is generated during the build process -->
<script src="build/main.js"></script>
<noscript>
This application needs JavaScript to work, please enable JavaScript on your browser
</noscript>
<script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async=""></script>
<script>
var OneSignal = window.OneSignal || [];
OneSignal.push(function () {
OneSignal.init({
appId: "XXXXXXXXXXXXXXXXXXXXX",
});
});
</script>
</body>
</html>
app.component.ts
in the method constructor
this.oneSignal.startInit('xxxxxx', 'xxxxxxxxxx');
this.oneSignal.inFocusDisplaying(this.oneSignal.OSInFocusDisplayOption.InAppAlert);
this.oneSignal.handleNotificationReceived().subscribe(data => this.onPushReceived(data.payload));
this.oneSignal.handleNotificationOpened().subscribe(data => this.onPushOpened(data.notification.payload));
this.oneSignal.endInit();
}
private onPushReceived(payload: OSNotificationPayload) {
alert(payload.body);
}
private onPushOpened(payload: OSNotificationPayload) {
alert(payload.body);
}
if anyone could help I would greatly appreciate it.

Facebook Can't scrape my Joomla website even when i added OG:tags

I have all the OG tags specified but Facebook still can't read my website. What's wrong?
Here is my HEAD section
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<base href="http://www.mojadebica.pl/kryminalne/1392-akcja-trzezwy-poranek-na-podkarpaciu" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="robots" content="index, follow" />
<meta name="keywords" content="Dębica, pizzerie, pizza, wyszukiwarka, jedzenie, na, wynos, dyżury, aptek, noclegi, reklama, strony www, portal, informacje, ogłoszenia, repertuar kin, oferty, pracy, forum, org, nasza" />
<meta name="og:image" content="http://www.mojadebica.pl/images/thumbs/poranek.jpg" />
<meta name="og:type" content="article" />
<meta name="title" content="Akcja 'Trzeźwy poranek' na Podkarpaciu" />
<meta name="og:title" content="Portal MojaDebica.pl" />
<meta name="og:url" content="http://www.mojadebica.pl/kryminalne/1392-akcja-trzezwy-poranek-na-podkarpaciu" />
<meta name="og:site_name" content="E-max" />
<meta name="og:description" content="Moja Dębica - najnowsze informacje i aktualności z Dębicy. Największa baza ofert pracy, ogłoszenia z dębicy i okolic oraz wyszukiwarka pizzy!" />
<meta name="description" content="Moja Dębica - najnowsze informacje i aktualności z Dębicy. Największa baza ofert pracy, ogłoszenia z dębicy i okolic oraz wyszukiwarka pizzy!" />
<meta name="generator" content="Joomla! 1.5 - Open Source Content Management" />
<title>Akcja "Trzeźwy poranek" na Podkarpaciu</title>
<link href="/templates/back-to-nature/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link rel="stylesheet" href="/media/system/css/modal.css" type="text/css" />
<link rel="stylesheet" href="/components/com_k2/css/k2.css" type="text/css" />
<link rel="stylesheet" href="/components/com_jcomments/tpl/default/style.css?v=12" type="text/css" />
<script type="text/javascript" src="/media/system/js/mootools.js"></script>
<script type="text/javascript" src="/media/system/js/modal.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/javascript" src="/components/com_k2/js/k2.js"></script>
<script type="text/javascript" src="/components/com_jcomments/js/jcomments-v2.1.js?v=7"></script>
<script type="text/javascript" src="/components/com_jcomments/libraries/joomlatune/ajax.js?v=3"></script>
<script type="text/javascript" src="/media/system/js/caption.js"></script>
<script type="text/javascript">
window.addEvent('domready', function() {
SqueezeBox.initialize({});
$$('a.modal').each(function(el) {
el.addEvent('click', function(e) {
new Event(e).stop();
SqueezeBox.fromElement(el);
});
});
});
var K2SitePath = '/';
</script>
<link rel="stylesheet" href="/templates/system/css/system.css" type="text/css" />
<link rel="stylesheet" href="/templates/system/css/general.css" type="text/css" />
<link rel="stylesheet" href="/templates/mdnew/stylemd4.4.css" type="text/css" />
<link rel="shortcut icon" href="/templates/mdnew/favicon.ico" />
<!--[if lte IE 6]>
<link href="/templates/back-to-nature/css/ieonly.css" rel="stylesheet" type="text/css" />
<![endif]-->
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-15391002-3']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
And here is sample article:
http://www.mojadebica.pl/video/1388-sonda-gdzie-jest-najlepsze-jedzenie-w-debicy-video-hd
Missing Required Property: The 'og:url' property is required, but not present.
but it's specified here:
<meta name="og:url" content="http://www.mojadebica.pl/kryminalne/1392-akcja-trzezwy-poranek-na-podkarpaciu" />
Your problem is with your webserver configuration.
In your response headers, your server is sending Content-Encoding: none. This is not valid.
There may be additional rules in there that are sending the Facebook parser a 403: Forbidden reply.
If you host with an ISP, contact them about this problem. If you're rolling your own server, you'll need to dig into the LiteSpeed documentation.