I am getting tagName of null error on razorpay integration. This error is related to head manager.
Link of github repository https://github.com/rajatgalav/razorpay-demo
I tried to debug it. And if i remove head component from index.js file, problem does not occur. But i want head component also in my project.
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<button onClick={displayRazorpay}>pay</button>
</main>
Head is imported from next/head package of NextJs
Nextjs adds default viewport meta tag <meta name="viewport" content="width=device-width">.
But razorpay script removes viewport meta tag and adds it's own version. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
And also adds theme-color meta tag <meta name="theme-color" content="#ff7400">.
Nextjs fails to detect these changes and tries to update the header. That's why you see this error when you go to success page.
So I am redirecting the user to success page by window.location = '/success' instead of using router.push('/success')
I am still investigating how to avoid the error when using router.
You could try this:
"modal": { "ondismiss": function(){ console.log('Checkout form closed'); const _window = window as any; _window.location = '/checkout'; }}
Also, add window.location in the handler function to navigate to another URL. Then you won't get that error.
I found a hack for this issue. Just add the razorpay script in the _document.js file. You can do it like this:
<Html lang="en">
<Head>
<script src="https://checkout.razorpay.com/v1/checkout.js" async></script>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
This fixed the issue for me.
Could you sort this issue ? The handler function in the Razorpay is causing this issue, though it is required. If that is removed this error is not appearing on navigation
When I get under a subdirectory in react router index.html links and scripts fail to load.
:1 Refused to apply style from 'http://localhost:3000/solutions/css/default.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
When i'm in /foo routes, its fine.. But when I get under /foo/foo, I get this error. This route for example is /solutions/home. In the console error it get to /solutions and then from there tries to import scrs from index.html.. Am i missing something?
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" sizes="16x16" />
<meta
name="viewport"
content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="stylesheet" href="css/default.css" />
<link rel="stylesheet" href="css/component.css" />
<title>Neuroelectrics</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
It was an easy one.. after thinking and trying to debug a lot about React and React router, I realized that it was nothing with it (dumb), just added %PUBLIC_URL% to all linking files. The problem was that with react router index.html was trying to fetch these files under the router routes.
I'm trying to create a component (here named "meta-info") which renders a meta-tag with dynamic information (which is being fetched via Rest-Webservice) into the head-tag.
Problem is: In the processed html the component won't stay in the head but gets rendered into the body as the first element, and every script and style tag in the head which follows the component in the code also gets moved into the body. It's like the component automatically opens a body-tag. :-(
Anyone got a tip of how to achieve what I need?
<!DOCTYPE html>
<html lang="de" class="app-basic-an" ng-app="app">
<head>
<meta charset="utf-8">
<title ng-bind="$ctrl.title"></title>
<meta http-equiv="cache-control" content="no-cache, no-store">
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta-info></meta-info>
[...]
</head>
<body>
[...]
</body>
</html>
An AngularJS not allow views to set the page title and insert extra elements into the head.
Try to use additional module angularjs-viewhead for it
https://github.com/apparentlymart/angularjs-viewhead
var app = angular.module('myApp', ['viewhead']);
<meta view-head name="description" content={{metaDescription}}>
Based on superluminary response here I've set up an Angular 1 app without Hashbangs and html5Mode(true) and rely on Google to execute javascript. The page is being indexed by Google but dynamic titles and description tags are not.
My index.html head is the following:
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<base href="/">
<meta name="author" content="me">
<meta name="robots" content="index,follow">
<title ng-bind="meta.title">Temp Title</title>
<meta name="description" content="{{meta.description}}">
<!-- Scripts & CSS -->
</head>
The title and description are correctly loaded but they don't display on Google.
How can I do that?
Also does this technique works with Facebook and other social networks? Thank you.
Why you don't use something like that?
https://github.com/steeve/angular-seo
Actually superluminary response here has the solution. HTML page head must be sent fully resolved by the server.
So in order for this solution to work I was forced to replicate angular routes in the server side and send the info resolved.
Instead of using a plain html view I changed to .ejs and also changed the header to something like this:
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<base href="/">
<meta name="robots" content="index,follow">
<script type="text/javascript">
window.title = <%- JSON.stringify(precomposition) %>.title;
</script>
<title ng-bind="title"><%= precomposition.title %></title>
<meta name="description" content="<%= precomposition.description %>">
<!-- More meta information -->
<!-- Scripts & CSS -->
</head>
Now when the website gets a direct hit (initially resolved by the server instead of Angular, always the case for crawlers) I handle the request server side:
//Express route
app.route('/').get(precomposition.render);
//precomposition
exports.render = function (req, res) {
const precomposition = {title: 'tile', description: 'description'};
res.locals.precomposition = precomposition;
res.render('index.ejs');
};
If it's not a direct hit Angular handles the title update (because the other info is not displayed to the user).
It has off course some downsides but Google since October 2015 recommends this approach instead of "_escaped_fragment_ URLs". Also I think it's a lot less resource consuming than the selfhosted pre-render alternatives and cheaper than the paid ones.
I was working on a single page application in react.js, so what is the best way to update meta tags on page transitions or browser back/forward?
I've used react-document-meta in an older project.
Just define your meta values
const meta = {
title: 'Some Meta Title',
description: 'I am a description, and I can create multiple tags',
canonical: 'http://example.com/path/to/page',
meta: {
charset: 'utf-8',
name: {
keywords: 'react,meta,document,html,tags'
}
}
and place a
<DocumentMeta {...meta} />
in the return
You can use react-meta-tags. It allows you to write title and other meta tags in a declarative way and in normal jsx format, which will be moved to head (Check server usage on the doc).
import React from 'react';
import MetaTags from 'react-meta-tags';
class Component1 extends React.Component {
render() {
return (
<div class="wrapper">
<MetaTags>
<title>Page 1</title>
<meta id="meta-description" name="description" content="Some description." />
<meta id="og-title" property="og:title" content="MyApp" />
<meta id="og-image" property="og:image" content="path/to/image.jpg" />
</MetaTags>
<div class="content"> Some Content </div>
</div>
)
}
}
You may also like to check react-helmet if you have an advanced use case.
You almost definitely want to use:
React Helmet
In contrast to react-meta-tags it can nest <Helmet>s and so you can define your meta tags deep within your app - like <title>s that should override each other. And in contrast to react-document-meta you can define things using jsx (and nest things).
This seems to be the solution that the community almost exclusively uses - 600,000 weekly downloads vs the 6,000 given in other solutions. "Helmet takes plain HTML tags and outputs plain HTML tags. It's dead simple, and React beginner friendly." - and has support for server-side rendering.
Here's an example, adapted from the front page:
<Parent>
I'm a parent
<Helmet>
<title>My Title</title>
<meta name="description" content="Helmet application" />
</Helmet>
<Child>
I'm a child
<Helmet>
<title>Nested Title</title>
<meta name="description" content="Nested component" />
</Helmet>
</Child>
</Parent>
outputs:
<head>
<title>Nested Title</title>
<meta name="description" content="Nested component">
</head>
<Parent>
I'm a parent
<Child>
I'm a child
</Child>
</Parent>
You cand also give the page title and meta tags description in the following way.
place a meta tag of description in your index.html file like this.
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<title>Dynamic Page title here</title>
in your .js files or .jsx files below the render() method write the page title and meta description for the page like this .
render()
{
document.title ="Welcome | here is your page title to display";
document.getElementsByTagName("META")[2].content="Your description about the page or site here to set dynamically";
return(
<div>Page content</div>
);
}
Firstly if you don't need dynamic data you can just edit public/index.html.
For dynamic data the React team recommends to either use react-helmet
import React from "react";
import { Helmet } from "react-helmet";
class Application extends React.Component {
render () {
return (
<div className="application">
<Helmet>
<meta charSet="utf-8" />
<title>React app</title>
<meta name="description" content="React application" />
</Helmet>
...
</div>
);
}
};
Or using placeholders and replacing them server-side:
<html lang="en">
<head>
<meta property="og:title" content="__OG_TITLE__" />
<meta property="og:description" content="__OG_DESCRIPTION__" />
</head>
</html>
According to the official documentation React Doc - Title and Meta Tags, you can also use React Helmet
You can use the document query and update their values.
const setTitle = title => {
const el = document.querySelector('title');
el.innerText = `${el.text} | ${title}`;
};
const setDescription = desc => {
const el = document.querySelector("meta[name='description']");
el.setAttribute('content',desc)
}
As create-react-app docs mentioned:
If you need to dynamically update the page title based on the content, you can use the browser document.title API. For more complex scenarios when you want to change the title from React components, you can use React Helmet, a third party library.
A simple example:
function App(){
document.title = "Home";
return (
<div>...</div>
)
}
Maybe it's late but you can do this very simply like this:
Just use useEffect() in your component like:
useEffect(() => {
document.head.innerHTML+=`
<meta name='description' content='My description value!!!'/>
<meta name='keywords' content='My keywords!!!'/>
`
}, []);
Not sure if this is the answer you were looking for but I was searching for how to update the info your react app shows when you preview the link in some other app. Every solution I tried wasn't working with github pages and react (react-helmet, react-meta-tags, react-document-meta). What ended up working was that you can edit the index.html located inside the public folder to change this info. Include this somewhere in the head:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/IMDB.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<title>IMDB</title>
<meta property="og:audio" content="http://example.com/bond/theme.mp3" />
<meta property="og:description"
content="Sean Connery found fame and fortune as the
suave, sophisticated British agent, James Bond." />
<meta property="og:determiner" content="the" />
<meta property="og:locale" content="en_GB" />
<meta property="og:locale:alternate" content="fr_FR" />
<meta property="og:locale:alternate" content="es_ES" />
<meta property="og:site_name" content="IMDb" />
<meta property="og:video" content="http://example.com/bond/trailer.swf" />
Example from https://ogp.me/
import React from 'react'
import { Helmet, HelmetProvider } from 'react-helmet-async';
const MetaData = ({ title }) => {
return (
<HelmetProvider>
<Helmet>
<title>{`${title} - title description`}</title>
</Helmet>
</HelmetProvider>
)
}
export default MetaData