Open grievouz opened 2 years ago
This sounds like a more generalized version of https://github.com/vitejs/vite/issues/3000#issuecomment-1059930509, which I like! I think Vite can expand more on the default set of tags to convert into imports, before needing to resort to a import:
directive.
Currently the set is defined here, and could be easily expanded out I think. html-loader has a great set of defaults that we could reference. I've applied the same for a Svelte preprocessor I made too.
Your comment is precisely what I was elaborating on in the alternative I provided. Though I believe that in my haste to write the issue, I dismissed it too quickly. I agree with you that it's probably ideal to expand on the default set before attempting to add unique syntax.
Hey guys, I came from #5292
I can't seem to get vite
to display my open graph image. I might be overlooking this but here is my code:
import { FC } from 'react';
import { Helmet } from 'react-helmet-async';
interface Props {
title?: string;
description?: string;
image?: string;
}
export const SEO: FC<Props> = ({ title, description, image }) => {
const pageTitle = title || 'PEPhub';
const pageDescription =
description || '...';
const pageImage = image || '/og-image.png';
const pageUrl = '...';
const pageType = 'website';
return (
<Helmet>
<title>{pageTitle}</title>
<meta name="description" content={pageDescription} />
<meta property="og:description" content={pageDescription} />
<meta property="og:title" content={pageTitle} />
<meta property="og:image" content={pageImage} />
<meta property="og:type" content={pageType} />
<meta property="og:url" content={pageUrl} />
</Helmet>
);
};
I can inspect the HTML on the browser and see that its putting in og-image.png
. moreover, I can grab it at http://my-host/og-image.png
. However, it doesn't render as a preview using all my local testing tools. I also cant see it with vite build && vite preview
.
Any help is appreciated!
I think I had a similar issue where I was trying to import the favicon from a location outside of the app. I have defined a ~
alias to point to the root of the project, but found that paths starting with ~/
do not resolve in index.html. I solved it as follows in vite.config.js
, which may provide a path forward for folks that need to do something similar:
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig(({ mode }) => {
function pathResolver(mode) {
// Resolves ~ in index.html
return {
name: "path-resolver",
transformIndexHtml: {
order: "pre",
handler(html) {
// Paths must be handled differently depending on mode
let resolvedPath = mode == "development" ? "@fs" + path.resolve(__dirname, "..") : "..";
return html.replace(new RegExp("~/"), resolvedPath + "/");
}
}
}
}
return {
plugins: [pathResolver(mode)],
resolve: {
alias: {
'~': path.resolve(__dirname, '..'),
},
},
...
}
})
Now the following works in index.html both dev and build/preview:
<link rel="icon" type="image/svg+xml" href="~/common/images/favicon.svg" />
I've found a hack to the this work with a simple config, it might not be your cup of tea, but it works to have the full path to OG image meta tags.
The idea is to to remove hashes from the generate filenames:
https://www.fabiofranchino.com/log/how-to-remove-hashing-in-vite-built-file-names/
Then I simply add this at the import section of my main.js
file
import prev from '../assets/preview.png';
Then I can hardcode the domain in the meta
tags.
Are there any simple workarounds?
Looks like useSeoMeta
from unhead is a good solution for Vue/Nuxt users.
Meta property content type can be a simple string, but something this string is a static assets path.
The most common examples are the meta properties for social network : og:image
and twitter:image
whose need a path to an image.
<meta property="og:image" content="/src/og-image.jpg" />
<meta property="twitter:image" content="/src/twitter-image.jpg" />
But Vite build handle this type of assets for now, even if the images exist locally.
Here is a stackblitz link that reproduce the issue.
If you run npm run build
and look at the assets folder, you'll see the build image of body-image.jpg
but none of the images used in meta property tag og-image.jpg
and twitter-image.jpg
.
This issue is particularly troublesome because there's no obvious visual side effect. It's only apparent when testing the Open Graph features (for example, sharing on social media).
Clear and concise description of the problem
Vite or rather the html entry plugin only resolves some attributes of some tags in index.html. For example
<link rel="icon" type="image/svg+xml" href="/src/assets/favicon.svg" />
will be compiled to<link rel="icon" type="image/svg+xml" href="/assets/favicon.[id].svg" />
I encountered it during the process of optimizing my website for social sharing through the addition of meta tags like
<meta property="og:image" content="<%- VITE_APP_HOST_URL %>/assets/og-image.jpg" />
As you can see already, I solved the problem by using env variables and the public folder to serve the images as static files, which I personally strongly detest due to the issues or inconsistencies that can arise from caching.I looked through the other issues and if I understood them properly this issue is also related to #5098 and #2270
Suggested solution
My suggestion would be to add a directive, or whatever other name will be used if this is implemented, to allow the user to explicitly add an attribute that should be resolved by the html plugin.
Let's take my meta tag from the above example:
<meta property="og:image" content="<%- VITE_APP_HOST_URL %>/assets/og-image.jpg" />
could then be changed to<meta property="og:image" content="import:/src/assets/og-image.jpg" />
and would be compiled to<meta property="og:image" content="/assets/og-image.[id].jpg" />
This could also be taken one step further or just for consistency by allowing for suffixes like
?url
,?raw
or?inline
.My simple implementation to test my proposal added about 20 lines of code, but it didn't add support for the suffixes or accounted for something like the
srcset
attribute.Alternative
An alternative would be to just add a config option for users to define the additional tags and the corresponding attributes that should be resolved by the plugin. Though without additional filter logic, this could result in additional problems. Let's take my example again, I would want it to resolve my
<meta/>
tags with thecontent=""
attribute but I would want it to ignore<meta/>
tags with the attributeproperty="og:description"
orproperty="og:title"
due to the fact that those contain just some text.Additional context
No response
Validations