I want to add meta tags on a React component with plain javascript without external libraries. I've added it in useEffect
hook like this:
useEffect(() => {
const ogTitle = document.createElement('meta');
const ogImage = document.createElement('meta');
const ogDescription = document.createElement('meta');
if(classPage?.name) {
ogTitle.setAttribute('property', 'og:title');
ogTitle.content= classPage?.name;
document.getElementsByTagName('head')[0].appendChild(ogTitle);
}
if(classPage?.pictureUrl) {
ogImage.setAttribute('property', 'og:image');
ogImage.content= classPage?.pictureUrl;
document.getElementsByTagName('head')[0].appendChild(ogImage);
}
if(classPage?.description) {
ogDescription.setAttribute('property', 'og:description');
ogDescription.content= classPage?.description;
document.getElementsByTagName('head')[0].appendChild(ogDescription);
}
const ogUrl = document.createElement('meta');
ogUrl.setAttribute('property', 'og:url');
ogUrl.content = document.location.href;
document.getElementsByTagName('head')[0].appendChild(ogUrl);
}, [classPage]);
And I can see the result when I open chrome inspector, they are there in the head
tag. But when I go to some other page I see that meta tags are appending below instead of replacing the values from the previous page. Like this:
<meta property="og:url" content="http://localhost:3000/ClassReadOnly/testing21186f6938be44682b8ccdc95827344b5">
<meta property="og:title" content="Testing 2">
<meta property="og:image" content="https://images.unsplash.com/photo-1616008783091-189d8c5efd61?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxODkyMzl8MHwxfHJhbmRvbXx8fHx8fHx8fDE2MjEzMzUzMzY&ixlib=rb-1.2.1&q=80&w=1080">
<meta property="og:description" content="testing">
<meta property="og:url" content="http://localhost:3000/ClassReadOnly/testing21186f6938be44682b8ccdc95827344b5">
<meta property="og:url" content="http://localhost:3000/ClassReadOnly/myfirstclasscc319a1ab57e4874be991a346e6fa86e">
<meta property="og:title" content="My First Class">
<meta property="og:image" content="https://images.unsplash.com/photo-1623001398544-5c7f047842ca?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxODkyMzl8MHwxfHJhbmRvbXx8fHx8fHx8fDE2MjM4NjAwMjA&ixlib=rb-1.2.1&q=80&w=1080">
<meta property="og:description" content="jhlghjul iuiuiu iouiuii">
<meta property="og:url" content="http://localhost:3000/ClassReadOnly/myfirstclasscc319a1ab57e4874be991a346e6fa86e">
<meta property="og:url" content="http://localhost:3000/ClassReadOnly/testing21186f6938be44682b8ccdc95827344b5">
<meta property="og:title" content="Testing 2">
<meta property="og:image" content="https://images.unsplash.com/photo-1616008783091-189d8c5efd61?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxODkyMzl8MHwxfHJhbmRvbXx8fHx8fHx8fDE2MjEzMzUzMzY&ixlib=rb-1.2.1&q=80&w=1080">
<meta property="og:description" content="testing">
<meta property="og:url" content="http://localhost:3000/ClassReadOnly/testing21186f6938be44682b8ccdc95827344b5">
I tried with cleanup function like this:
return () => {
ogTitle.removeAttribute('property')
ogTitle.content = '';
document.getElementsByTagName('head')[0].removeChild(ogTitle)
......
}
But got this error:
NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
So my question is how to achieve adding meta tags in React component with plain javascript, NO libraries
As mentioned the issue seems to be that you are creating the element every time. In my opinion it would be an idea to just make a meta adder function as below:
const metaAdder = (queryProperty, value) => {
// Get an element if it exists already
let element = document.querySelector(`meta[${queryProperty}]`);
// Check if the element exists
if (element) {
// If it does just change the content of the element
element.setAttribute("content", value);
} else {
// It doesn't exist so lets make a HTML element string with the info we want
element = `<meta ${queryProperty} content="${value}" />`;
// And insert it into the head
document.head.insertAdjacentHTML("beforeend", element);
}
};
You can then call this function and pass the property/name of the meta tag you wish to change along with the value. If the meta tag exists it will change the content otherwise it will create and insert it.
In your example:
if(classPage?.name) {
metaAdder('property="og:title"', classPage.name)
}
I have removed your second check for the existence of className as we have already checked that in the wrapping if statement.
If you wish to change a property other than the content you can alter the function to take an object.