Closed Balamir closed 4 years ago
@Balamir could you give us some code for this? Where we can work on locally.
Please re-open this issue after that.
@arunoda thanks for the reply.
I just tried this with your head-elements example.
Simply I added above meta:
import Head from 'next/head'
export default () => (
<div>
<Head>
<title>This page has a title 🤔</title>
<meta charSet='utf-8' />
<meta name="description" content="That's it!" />
<meta name='viewport' content='initial-scale=1.0, width=device-width' />
</Head>
<h1>This page has a title 🤔</h1>
</div>
)
and the result:
Thanks.
Thanks. I'll see what's happening here.
@arunoda I couldn't reopen this issue. It's still closed. Can you re-open this issue please?
Thanks.
This Issue still exist .For single quote it is rendering as '
clothing,men's shoes,men's accessories,women's clothing,women's shoes,jewelry,women's handbags,women's accessories,dogs,furniture,home and decor,kitchen and dining
The same is true for urls.
Adding <meta property="og:image" content="http://example.com?foo=bar&bar=baz" />
results in <meta property="og:image" content="http://example.com?foo=bar&bar=baz" class="next-head"/>
.
Notice the encoded &
. Any way around that?
I'm facing the same issue. Are there any updates on it?
I'm expecting this is an upstream React SSR issue, since we don't escape values afaik.
Running through the same issue. any workaround please ?
I've made a workaround by post-processing the generated HTML and using a regex for the attributes that are incorrectly encoded with HTML entities:
https://gist.github.com/stefl/1f8c246dd7ca9cb332ae41f68e80088d
Obviously not a long-term fix but it means that my Opengraph metadata is now not affected by this. Hope this is of use to others here!
Please track https://github.com/facebook/react/issues/13838. I'm using the following workaround:
import Entities from 'html-entities/lib/html5-entities'
const entities = new Entities()
const escapeRegExp = /(content|href|src|srcSet)="([^"]+)"/g
const escapeHandle = (match, attribute, value) => {
return `${attribute}="${entities.decode(value)}"`
}
// ...
html = html.replace(escapeRegExp, escapeHandle)
Still have the same issue...
@mrasoahaingo it's not really relevant to post "same issue", as @oliviertassinari said it's an upstream issue. If the issue is open you can consider it's still there an not solved, so saying "same issue" is not really useful, if you want to "+1" an issue use GitHub's reaction system on the initial post to 👍
Thanks.
@timneutkens After 2 years it's normal to see people saying that the issue still there.
The last comment before the "same issue" clearly said it's a bug in React, the issue on React's side is still open, hence why it's not valuable to say something along the lines of "Same issue...", it doesn't add value, this is why the emoji reactions exist in GitHub.
React Helmet has a encodeSpecialCharacters
boolean prop to disable the encode server side. Can it be done on next-head too?
Seems like Helmet completely bypasses React, which doesn't seem like a good idea imo.
Closing this as it's tracked on React: https://github.com/facebook/react/issues/13838
We are migration the application to next.js we have been using helmet and I tried to migrated to next/head but I found the error with for example the http://schema.org data for example to use
<script type="application/ld+json">
{"@context":"http://schema.org","@type":"BreadcrumbList" ...
</script>
next/head convert it to, but with react-helmet return the expect value
<script type="application/ld+json">
"@context": "http://schema.org",
"@type": "SportsEvent",
</script>
@vxcamiloxv Have you tried with making it a string?
Like:
<script type="application/ld+json">{`
{"@context":"http://schema.org","@type":"BreadcrumbList" ...
`}</script>
Can't remember, but think I made that work once :)
@DesignMonkey yes, my final solution was <script ype="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(json) }} />
@vxcamiloxv Oh yea sure... Maybe that was the solution I ended up with as well :)
@vxcamiloxv Thank you for sharing your solution! I have used it to get the proper behaviour:
const ldJSON = `<JSON goes here>`
....
and then
in return (<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: ldJSON }}/>)
@oliviertassinari Where do you put this code ? I understand it's a react problem, but where do you parse the meta tag on Next.js ? If I do it on my page, I still have the escaped text in my head.
Example :
const escapeRegExp = /(content|href|src|srcSet)="([^"]+)"/g;
const escapeHandle = (match, attribute, value) => {
return `${attribute}="${decode(value)}"`;
};
const metaTagEscaped = "default-src * 'self' data: 'unsafe-inline' 'unsafe-eval' *; child-src * 'self' data: 'unsafe-inline' 'unsafe-eval' *; script-src 'unsafe-inline' 'self' https://js.stripe.com/v3".replace(
escapeRegExp,
escapeHandle
);
<Head>
<title>{translatedPageTitle}</title>
<meta
http-equiv="Content-Security-Policy"
content={metaTagEscaped}
></meta>
</Head>
This doesn't work and still gives me escaped characters.
@dzinemon so you write a meta tag this ay ? I don't get how to implement it.
Found a workaround for &
in the image url in next.js — the main issue was the imgix params in the URL weren't sticking, due to the escaped ampersands. So I took the properties out of the meta tag, and wrote a backend proxy to deliver the image data directly:
So in your template:
const shareImage = myfile.jpg // without any query params
<meta property="og:image" content={`/api/share?image=${shareImage}`} />
Then in api/share.js
:
import request from 'request'
export default async function share(req, res) {
const { image } = req.query
if (image) {
request
.get(image + '?fm=jpg&q=80&w=1402&h=738&fit=crop&crop=faces,edges')
.pipe(res)
} else {
res.status(404).json({})
}
}
Probably need to validate the incoming url, otherwise it could be open for malice, but this fixes the issue until this is merged in: https://github.com/facebook/react/issues/13838
Found a workaround for
&
in the image url in next.js — the main issue was the imgix params in the URL weren't sticking, due to the escaped ampersands. So I took the properties out of the meta tag, and wrote a backend proxy to deliver the image data directly:So in your template:
const shareImage = myfile.jpg // without any query params
<meta property="og:image" content={`/api/share?image=${shareImage}`} />
Then in
api/share.js
:import request from 'request' export default async function share(req, res) { const { image } = req.query if (image) { request .get(image + '?fm=jpg&q=80&w=1402&h=738&fit=crop&crop=faces,edges') .pipe(res) } else { res.status(404).json({}) } }
Probably need to validate the incoming url, otherwise it could be open for malice, but this fixes the issue until this is merged in: https://github.com/facebook/react/issues/13838
Thanks. Unfortunately i don't think that issue on Fb will merged. It is 3yrs old.
I used the Next.js _document
file to replace all the &
occurrences. I am using some code from @stefl gist to do the replacement.
The main point is to use _document
to handle this issue, so please ignore the code.
My use case were images with w and h query parameters being incorrectly used by the crawlers since those pages were made with getStaticProps and they all had &
instead of &
.
// _document.tsx
import { decode } from 'html-entities';
const srcRegex = /src="([^"]+)"/g;
const srcSetRegex = /srcSet="([^"]+)"/g;
const decodeHtmlEntities = (html: string): string =>
html
.replace(srcRegex, (match: string, content: string) => {
return `src="${decode(content)}"`;
})
.replace(srcSetRegex, (match: string, content: string) => {
return `srcSet="${decode(content)}"`;
});
class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
const html = decodeHtmlEntities(initialProps.html);
return { ...initialProps, html };
}
...
// encoded.tsx page
const Page = () => {
const imageUrl = 'https://makelight-prismic-images.imgix.net/7f97d951970bbb15a8b3744e4c69499ffe969d66_img_1010.jpg';
const defaultImageParameters = 'w=1024&h=768';
const largeImageParameters = 'w=1920&h=1080';
const src = `${imageUrl}?${defaultImageParameters}`;
console.log(src);
return <img alt="Some image" src={src} srcSet={`${src} 1024w, ${imageUrl}?${largeImageParameters} 1920w`} />;
};
export default Page;
P.S. you can move decodeHtmlEntities
in an util file decodeHtmlEntities.ts
, e.g.:
import { decode } from 'html-entities';
const decodeHtmlEntitiesRegex = /(content|href|src|srcSet)="([^"]+)"/g;
export const decodeHtmlEntities = (html: string): string =>
html.replace(
decodeHtmlEntitiesRegex,
(match: string, attribute: string, value: string) => `${attribute}="${decode(value)}"`
);
See the images attached. First one is showing before the replace, and second one with the fix. Third one is to show also srcSet. There are also Node and Chrome logs showing how they didn't have issue anyway.
@timneutkens is using _document
to do this replace okay?
Kudos to @isBatak for finding this out.
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
Hi,
I'm facing an issue with meta tags. When I use some special characters like single quote in the head tag, it's escaping. I can not use
dangerouslySetInnerHtml
for meta tags.in code:
<meta name="description" content="That's it!" />
result:
<meta name="description" content="That's it!" />
How can I handle with this? I couldn't find any solution about this problem.
Thanks.