The icon doesn't show in production nextjs - reactjs

The meta link icon doesn't show in production nextjs but shows in localhost.
code:
const Home: NextPage<HomeProps> = () => {
return (
<div>
<Head>
<title>The Stobook</title>
<meta
name="description"
content="The Stobook is an open library where you can read any book for free. It features a customizable auto function that suggests depending on user preferences."
/>
<link rel="icon" href="/book.ico" />
</Head>
<div className={styles.index__container}>
//SomeCode
</div>
</div>
);
};
book.ico is in public folder.
It works in localhost, but doesn't show after I deployed it into vercel.
I also tried import the book.ico and href={icon.src} but thats causes error.

Issue could be related to two reasons
If you have a basePath defined in your next.config.js then your path becomes - /basepath/book.ico
NextJS vercel hosting issue - Try adding it to a images folder inside root - i.e
i.e
<link rel="icon" type="image/x-icon" href="/images/book.ico" />

Related

head tag not appearing in view source : next:js

i have created my next js appp where i have implemented my head tag but when i check the view source by right clicking i dont see my title and meta tags there how can i achive that?
eventhough the head tag is missing in view souce it can be found in inspect element
<Head>
<title> {itm.Name} - wixten </title>
<link rel="shortcut icon" href="/wixten.png" />
<meta
name="viewport"
content="initial-scale=1.0, width=device-width"
/>
<meta name="description" content={itm.Summary} />
<meta charSet="utf-8" />
<meta property="og:title" content={itm.Name} />
<meta property="og:description" content={itm.Summary} />
<meta property="og:image" content="images/wixten.png" />
<meta property="og:locale" key="og:locale" content="en_US" />
<meta property="og:type" key="og:type" content="website" />
<meta
property="og:url"
key="og:url"
content={`${baseurl}${itm._id}`}
/>
</Head>
i am adding full code in codesandbox
https://codesandbox.io/s/sweet-franklin-gpht9?file=/pages/index.js
the website i am faceing issue is this
https://wixten.com/query/61f4f5f9e41f700023c833c0
Your title and meta tags aren't appearing in your source code because you're fetching them client-side, after the page loads.
In order to include them in the source code, they need to be fetched ahead of time, either through Server-Side Rendering (SSR) or through Static Site Generation (SSG). The Next docs cover these options thoroughly.
Assuming you want to go the SSR route, you'd do the following:
export async function getStaticProps(context) {
const res = await axios.get(...);
return {
// will be passed to the page component as props
props: {
Item: res.data
},
}
}
Then you can use it in your component like this:
function MyPageComponent({ Item }) {
return (
<Head>
<title>{Item.name}</title>
</Head>
)
}
Just in case if anyone is facing the same issue like this, please check your _document.jsx to see if it matches the SSR requirements. If it is not set up then the meta tag won't show up.
You would need to include your meta tags there as well.
You have to call your head in the return otherwise it won't appear on the client side
You can use Next.js Head to set the title
import Head from "next/head";
const Home = () => {
return (
<div>
<Head>
<title>your title</title>
</Head>
// code
</div>
);
};
I had the same problem, re-launching a new tab with localhost:3000 solved the issue in my case.
I didn't see this mentioned here, and there are a few other questions on SO that also fail to address the solution that I needed (many reference importing Head from the right place, etc.).
All I had to do was change fallback to "blocking" from true in getStaticPaths. Immediately resolved.

loading script in react components which is in same folder

This might be simple question but I couldn't figure out how to load the external script which is in the same folder using relative path. Below is the src folder snapshot.
Here I am trying to import draggable.js inside the DesignScreen.js components. Here the defined components.
import React from 'react'
import './decorate.css'
const DesignsScreen = () => {
React.useEffect(() => {
const LoadExternalScript = () => {
const externalScript = document.createElement('script')
// externalScript.onerror = loadError;
externalScript.id = 'external'
externalScript.async = true
externalScript.type = 'text/javascript'
externalScript.setAttribute('crossorigin', 'anonymous')
document.body.appendChild(externalScript)
externalScript.src = './draggable.js'
}
LoadExternalScript()
}, [])
return (
<>
<div
id='draggable'
draggable='true'
style={{ backgroundPosition: '0px 0px' }}
></div>
</>
)
}
export default DesignsScreen
I want to load draggable.js without using full path like this: externalScript.src = './draggable.js'. I have googled it for the solution without success. So, I turned up here looking for answer.
If you make your project with CRA, you could just add your external script to public/index.html.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<-- Add your script here -->
<title>React App</title>
</head>
externalScript.src = '/src/screens/draggable.js' once try this in our project we are importing script files like this.
Remember that if you are working with external scripts, then the ./ in your externalScript.src is the public directory. After you build your React app there won't be a src folder anymore, just the public folder.
src/screens/ProductBase/DesignsScreen.js file:
let externalScript = document.createElement('script');
externalScript.src = './draggable.js';
externalScript.async = true;
document.body.appendChild(externalScript);
public/draggable.js file:
window.addEventListener('load', () => console.log("Hello World!"));
I tested this sample code and it works. When the browser loads the page the console logs "Hello World!".

Using react-helmet results into 2 sets of meta tags on react CSR page

I am using react-helmet for my react project.
Meta tags in my index.html are:
<link rel="canonical" href="https://example.com" />
<meta name="description" content="main description">
In components, I am setting meta tags as:
const ContactUs = () => {
return (
<div className="less-content-container justify-content-start align-items-start">
<Helmet>
<title>Contact Us | Example</title>
<meta name="description" content={"contact us description"} />
<link rel="canonical" href={"https://example.com/contact-us"} ></link>
</Helmet>
</div>
);
}
When final contact us page render in browser, I see two set of meta tags in the rendered html in Chrome inspect. First set of meta tags are that of index.html and second set of meta tags are that declared in component.
Also, in Google Webmasters console, I see User-declared canonical is set to none. That means. Google crawler didn't read canonical meta tag.
Got the exact same problem and fixed it by adding a data-react-helmet="true" attribute to the definition on my index.html. Something like this:
<meta name="description" content="main description" data-react-helmet="true" />
React Helmet should now replace the description on index.html upon startup.

How to Add html in React

I'm starting to learn reactjs at the moment. I'm wondering how to add normal HTML-Tags in a react-app. Is i just possible to add them by using the render function or can I also just write normal HTML-Tags in my index.html file?
Cause when I'm doing so they're not displayed.
Just like:
const myelement = (<h1>some element</h1>);
ReactDOM.render(myelement, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div>
<div id="root"></div>
<div>just normal html</div>
</div>
Well, it works just fine here.. so there must be something wrong with my build..
If you're starting out, I recommend you bootstrap your apps using npx create-react-app. It'll give you a good sense of what a React app could look like, and some pointers for file structure.
Most React apps have an index.html file, which you can use like any normal HTML file. But, for the majority of your app, it's recommended to write your content in JSX (otherwise, you aren't getting the benefits of using React in the first place).
JSX
JSX looks very similar to regular HTML, with a handful of key differences:
Tag attributes tend to be in lowerCamelCase (onChange rather than onchange)
Instead of class (which is a reserved keyword in JavaScript), you need to use className
An Example Component
I've borrowed this sample code from React's official tutorial, which you should definitely check out if you haven't already.
This is a class Component, and your JSX goes inside of the render method:
import React from 'react';
class ShoppingList extends React.Component {
render() {
return (
<div className="shopping-list">
<h1>Shopping List for {this.props.name}</h1>
<ul>
<li>Instagram</li>
<li>WhatsApp</li>
<li>Oculus</li>
</ul>
</div>
);
}
}
What goes in index.html?
The only essential part of index.html is a <div id="root"></div>, which React will use to append the rest of the JSX.
This is also the place to add the usual metadata and icons.
As an example, here's the index.html file that comes with create-react-app. For most of my projects, I leave this pretty-much as-is:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
In any given React component, there can only be one parent/top layer html element. You can get around this by using <React.Fragment> ...the rest of your html ... </React.Fragment> (or <>...</> depending on your version) or simply add a wrapping <div> around everything. JSX doesn't distinguish between "normal" html and "React" html, it just turns the React stuff into normal html (over simplification, but close enough for this question). Try it again and let me know if you encounter any problems.
const reactElement = (
<div>
React stuff
</div>
);
ReactDOM.render(
reactElement,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div>
<div id="root">
</div>
<div>
just normal html
</div>
</div>

CSS Transition flash on page load with NextJS production build

On my production build (npm run build && npm run start) of my NextJS app I noticed elements firing a css transition on page load (links flashing blue, svg flashing color).
Noticed in Chrome only, Firefox and Safari didn't have this problem.
Found the answer in this stackoverflow question. Appearantly it is due to a chrome bug (https://crbug.com/332189 and https://crbug.com/167083).
Fix is to put a script tag with one space at the end of the body. In NextJS you can do this by adding a pages/_document.js file (more info).
Mine looks like this now:
import Document, { Html, Head, Main, NextScript } from 'next/document';
export default class MyDocument extends Document {
render () {
return (
<Html lang="en">
<Head>
<meta charSet="utf-8" />
<meta name="viewport" content="initial-scale=1.0, width=device-width"/>
</Head>
<body>
<Main />
<NextScript />
{/* Empty script tag as chrome bug fix, see https://stackoverflow.com/a/42969608/943337 */}
<script> </script>
</body>
</Html>
)
}
}
Edit: This bug might be fixed since June 1st 2021 in Chrome Canary v93.0.4529.0 after 7.5 years!

Resources