jharris4 / html-webpack-tags-plugin

lets you define html tags to inject with html-webpack-plugin
MIT License
256 stars 31 forks source link

Add support for meta tag #50

Closed tkrotoff closed 5 years ago

tkrotoff commented 5 years ago

Currently html-webpack-tags-plugin supports <link> and <script>, but it does not support <meta>.

Use case: <meta name="msapplication-config" content="favicons/browserconfig.xml?8f58478fb4d4d32bcacf" />, see https://realfavicongenerator.net/

Full use case, add favicons to index.html and hash the filenames, example:

new HtmlWebpackTagsPlugin({
  // Generates:
  //
  // <link rel="apple-touch-icon" sizes="180x180" href="favicons/apple-touch-icon.png?8f58478fb4d4d32bcacf" />
  // <link rel="icon" type="image/png" sizes="32x32" href="favicons/favicon-32x32.png?8f58478fb4d4d32bcacf" />
  // <link rel="icon" type="image/png" sizes="16x16" href="favicons/favicon-16x16.png?8f58478fb4d4d32bcacf" />
  // <link rel="manifest" href="favicons/site.webmanifest?8f58478fb4d4d32bcacf" />
  // <link rel="mask-icon" href="favicons/safari-pinned-tab.svg?8f58478fb4d4d32bcacf" color="#007831" />
  // <link rel="shortcut icon" href="favicons/favicon.ico?8f58478fb4d4d32bcacf" />
  //
  // FYI The icons have been generated by RealFaviconGenerator v0.16 using favicon.svg
  links: [
    {
      path: './favicons/apple-touch-icon.png',
      attributes: { rel: 'apple-touch-icon', sizes: '180x180' }
    },
    {
      path: './favicons/favicon-32x32.png',
      attributes: { rel: 'icon', type: 'image/png', sizes: '32x32' }
    },
    {
      path: './favicons/favicon-16x16.png',
      attributes: { rel: 'icon', type: 'image/png', sizes: '16x16' }
    },
    {
      path: './favicons/site.webmanifest',
      attributes: { rel: 'manifest' }
    },
    {
      path: './favicons/safari-pinned-tab.svg',
      attributes: { rel: 'mask-icon', color: '#007831' }
    },
    {
      path: './favicons/favicon.ico',
      attributes: { rel: 'shortcut icon' }
    }
  ],

  // TODO Add missing meta tags
  //
  // <meta name="msapplication-TileColor" content="#da532c" />
  // <meta name="msapplication-config" content="favicons/browserconfig.xml?8f58478fb4d4d32bcacf" />
  // <meta name="theme-color" content="#ffffff" />
  /*
  metas: [
    { attributes: { name: 'msapplication-TileColor', content: '#da532c' } },
    { path: './favicons/browserconfig.xml', attributes: { name: 'msapplication-config' } },
    { attributes: { name: 'theme-color', content: '#ffffff' } }
  ],
  */
  append: false,
  hash: true
}),
jharris4 commented 5 years ago

Interesting idea but this plugin uses html-webpack-plugin to insert the tags and it only currently supports link or script tags.

It might be better to open this issue on that plugin first...

tkrotoff commented 5 years ago

Are you sure html-webpack-plugin does not handle <meta>? The alterAssetTags hook takes meta: Array<HtmlTagObject>

jharris4 commented 5 years ago

Ok, html-webpack-plugin does support meta tags, but only through options.meta, which you can see here

Basically, if you want to inject meta tags, you need to do so through the html-webpack-plugin options, something like:

plugins: [
  new HtmlWebpackPlugin({ meta: { "msapplication-config": { name: "msapplication-config", content: "favicons/browserconfig.xml" }),
  new HtmlWebpackTagsPlugin({ scripts: [], links: [] })
]

Can you give the above a try, and let me know if it works? ;-)

tkrotoff commented 5 years ago

If I use HtmlWebpackPlugin instead of HtmlWebpackTagsPlugin, file browserconfig.xml won't be hashed (it's then better to directly hardcode <meta name="msapplication-config" content="favicons/browserconfig.xml" /> inside index.html).

The use case is to have all favicons files to be hashed, something like <meta name="msapplication-config" content="favicons/browserconfig.xml?8f58478fb4d4d32bcacf" />.

Of course there is no hash (and thus no need to use HtmlWebpackTagsPlugin) for:

<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
jharris4 commented 5 years ago

Ok, I can see that being able to inject the publicPath or hash into the meta tag content attribute could be useful, so I've added a new option to allow that in version 2.0.14, along with several (passing) tests.

@tkrotoff Can you please try out the new option and let me know if it works for you? If so we can close this issue... ;-)

I've added the following example to the README. The example uses the publicPath, but works for hash as well.


Using the meta option to inject meta tags:

output: {
  publicPath: '/my-public-path/'
},
plugins: [
  new CopyWebpackPlugin([
    { from: 'node_modules/bootstrap/dist/js', to: 'js/'}
  ]),
  new HtmlWebpackPlugin(),
  new HtmlWebpackTagsPlugin({
    meta: [
      {
        path: 'asset/path',
        attributes: {
          name: 'the-meta-name'
        }
      }
    ]
  })
]

Will inject the following <meta> element into the index template html

<head>
  <!-- previous header content -->
  <meta content="/my-public-path/asset/path" name="the-meta-name">
</head>

Note that the append settings has no effect on how the <meta> elements are injected.

tkrotoff commented 5 years ago

Works great, thx!

However, the name meta feels wrong since there is scripts and links (and all of them take an array). I would have go for metas plural form.

jharris4 commented 5 years ago

I agree, but since this is really just using the html-webpack-plugin meta option under the covers, I decided to keep them the same.

tkrotoff commented 5 years ago

just using the html-webpack-plugin meta option under the covers

IMHO this is an implementation detail that users don't care about, they much prefer consistent APIs.

Anyway, it works wonderfully. Thanks a lot :-)

jharris4 commented 5 years ago

@tkrotoff after reflection I think you are correct that metas is a more consistent option name than meta.

I renamed it in version 2.0.15, shouldn't be a breaking change as nobody is using it yet.

tkrotoff commented 5 years ago

:-)