Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add meta option #419

Closed
wants to merge 2 commits into from
Closed

Add meta option #419

wants to merge 2 commits into from

Conversation

SimenB
Copy link
Contributor

@SimenB SimenB commented Sep 3, 2016

Only reason I still keep around a custom template

@jantimon
Copy link
Owner

jantimon commented Sep 4, 2016

could this also be a key value pair?

@SimenB
Copy link
Contributor Author

SimenB commented Sep 4, 2016

A single meta tag can have one or more attributes, so not really

@jantimon
Copy link
Owner

jantimon commented Sep 7, 2016

I was just thinking because we could set meaningful defaults if it would be named... but right now I don't have a good idea for that..

Maybe we can come up with something - otherwise I will merge this one

@jantimon
Copy link
Owner

jantimon commented Sep 7, 2016

Here is a list of all possible header values:

https://github.com/joshbuchea/HEAD#meta

@jantimon
Copy link
Owner

jantimon commented Sep 7, 2016

What about:

{ 
   'charset:utf8': true, 
   'http-equiv:x-ua-compatible': "ie=edge",
}

to get

<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">

That way we could come up with a good default and a user might then just unset a value e.g. x-ua-compatible:false

@SimenB
Copy link
Contributor Author

SimenB commented Sep 7, 2016

How would you infer content for example in that sample? Some sort of list of specific attributes?
This implementation works for every possible permutation of the meta tag, at the expense of a slightly clunky API. But the logic is minimal, and very easy to grok.

@SimenB
Copy link
Contributor Author

SimenB commented Sep 7, 2016

I'm with you on making it easy to add these (I think this should perhaps remove the ones from the default template, and add them through this API), but the current approach represents a simpler implementation to understand and maintain.

@jantimon
Copy link
Owner

jantimon commented Sep 7, 2016

Yes the api is kind of ugly ;)

And yes we should replace the default template attributes.

According to the list https://github.com/joshbuchea/HEAD#meta every setting is placed into content.

   {  'http-equiv:x-ua-compatible':        "ie=edge" }
          ↑                    ↑                ↑
<meta http-equiv="x-ua-compatible" content="ie=edge">

And if it is not content we would still have the opportunity to set it with an object instead of a string

@SimenB
Copy link
Contributor Author

SimenB commented Sep 7, 2016

So the key could ble split on colon, and the value could be placed in content? If so, I very much agree 😄 I took a look at how meta works now, and it seems to be the case

@SimenB
Copy link
Contributor Author

SimenB commented Sep 8, 2016

So you want

new HtmlWebpackPlugin({ meta: { 'charset:utf-8': null, 'http-equiv:x-ua-compatible': 'ie=edge' } })

?

@jantimon
Copy link
Owner

jantimon commented Sep 8, 2016

Yes I guess that would be nice - maybe we use = instead of :

new HtmlWebpackPlugin({ meta: 
{ 
  'charset=utf-8': null, 
  'http-equiv=x-ua-compatible': 'ie=edge' 
} 
})

what do you think?

@SimenB
Copy link
Contributor Author

SimenB commented Sep 8, 2016

@jantimon Updated now.

Not sure how to force it at the top of head.

@jantimon
Copy link
Owner

jantimon commented Sep 8, 2016

Hmm this is quite nice and you are right we should probably push it to the beginning of head.
The change is not backwards compatible and everyone who is using a custom template will have to adjust the template or the config.

@SimenB
Copy link
Contributor Author

SimenB commented Sep 8, 2016

We could drop changing the default template here, and release that as a separate thing (keep a PR open with the change until you're ready to release a v3

@jantimon
Copy link
Owner

jantimon commented Sep 8, 2016

Maybe we should just not use defaults and go with your initial proposal.

@jantimon
Copy link
Owner

jantimon commented Sep 8, 2016

Hmm but then the base template would be mixed

@SimenB
Copy link
Contributor Author

SimenB commented Sep 9, 2016

What do you want me to do? Drop the last commit? Or just the defaults in it?

@jantimon
Copy link
Owner

jantimon commented Sep 9, 2016

Hmm I really like the idea but I would like to try a different approach let me prepare a draft

@jantimon
Copy link
Owner

jantimon commented Sep 9, 2016

Okay sorry seems to take longer than I hoped because of webpack/webpack#2978
Tried a workaround but:
webpack/webpack#2979

@RPDeshaies
Copy link

Any status on this ?

@SimenB
Copy link
Contributor Author

SimenB commented Jan 26, 2017

Since v3 is coming, maybe merge this as is? I haven't touched it since the discussions happened

@SimenB
Copy link
Contributor Author

SimenB commented Jan 26, 2017

FWIW, I still prefer the original API, with an array of objects. Clean and easy, no inferrence or magic delimiters

@jantimon
Copy link
Owner

jantimon commented Jan 29, 2017

You are right - magic is almost every time a bad idea.
And yes this would be a good feature for 3.x

What about a mix of both of the ideas so we get defaults, an easy configuration for name:content pairs and full power if needed:

  {
      // <meta charset="utf-8">
      charset: { charset: 'utf-8' },
      // <meta name="google" content="notranslate">
      // <meta name="google" content="nositelinkssearchbox">
      google: ['notranslate', 'nositelinkssearchbox'],
      // <meta name="referrer" content="no-referrer">
   }
  1. if the value is an object we ignore the key (but we can set a default)
  2. if the value is an string or array we use the key as name and the value as content

@michael-ciniawsky
Copy link
Contributor

Why not just simply a [Template] String ?

// {String}
new HTMLPlugin({
  meta: `
    <meta charset="utf8">
    <meta ...>
 `
})

// {Function}
new HTMLPlugin({
  meta: (ctx) => `
    <meta charset=${ctx.charset}>
    <meta ...>
    <meta ...>
 `
})

@jantimon
Copy link
Owner

jantimon commented Mar 20, 2018

Sorry for postponing the topic for so long.
The request came again in #897 .

What about the following structure:

{
  charset: { 'charset': 'utf-8' },
  viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no',
  'Content-Security-Policy': { 'content': 'default-src "self"', 'http-equiv': 'Content-Security-Policy'},
}

This would allow a very extensible api with defaults.
Some defaults could look like the following object:
(Please jump in and improve the default object)

{
  charset: { 'charset': 'utf-8' },
  viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'
}

And could easily be overwritten e.g.

new HtmlWebpackPlugin({
  meta: {
    viewport: false, 
    // or
    viewport: width=500, initial-scale=1
  },
}

And the default could easily be extended:

new HtmlWebpackPlugin({
  meta: {
    referrer: 'no-referrer'
  },
}

The following function would convert it internally into the structure you proposed initally:

function getMetaTagArray(meta) {
  if (meta === false) {
    return [];
  }
  const metaObjects = Object.entries(meta).map(([metaName, value]) => {
    return (typeof value === 'object') ? value : {
      name: metaName,
      content: value
    };
  });
  return metaObjects;
}

@jantimon jantimon mentioned this pull request Mar 20, 2018
@SimenB
Copy link
Contributor Author

SimenB commented Mar 20, 2018

Hah, completely forgot about this. 😀

How would you do meta tags without name, like <meta http-equiv="X-UA-Compatible" content="IE=Edge"> or Open Graph tags: <meta property="og:image:width" content="1200"> with that API? I suppose extra name doesn't hurt (although I don't know), like your example with charset would be

@jantimon
Copy link
Owner

@SimenB haha me too 😉

Just like the 'Content-Security-Policy' example:

{
  'og:image:width' : {
     property: 'og:image:width',
     content: 1200
  }
}

I created an interactive example to play around:

https://codepen.io/anon/pen/RMprbX?editors=0010

@SimenB
Copy link
Contributor Author

SimenB commented Mar 20, 2018

Ah, so if the value is an object, that's used as is, but if the value is a string, its key becomes name? Sounds good 🙂

@mastilver
Copy link
Collaborator

mastilver commented Mar 20, 2018

What about having an array directly: less moving parts, easier for the user to understand

new HtmlWebpackPlugin({
  meta: [
    {
      "charset": "utf-8"
    },
    {
      "name": "viewport",
      "content": "width=device-width, initial-scale=1, shrink-to-fit=no"
    },
    {
      "property": "og:image:width",
      "content": "1200"
    }
  ]
}

A bit longer tough.
Either way I'm fine with the object based one :)

EDIT: Just realised, I was reiterating something that was already proposed earlier... -_-

@SimenB
Copy link
Contributor Author

SimenB commented Mar 20, 2018

Yeah, that's the API of my original commit if you look at the history. 🙂 FWIW I still think that'd be the cleanest solution, but I have nothing in particular against @jantimon's latest suggestion either

@jantimon
Copy link
Owner

I totally agree that the array looks easier but it’s harder to modify as it it number based.
So we could not provide any defaults or offer only a all or nothing preset.

@jantimon
Copy link
Owner

Moved to #906.

@jantimon jantimon closed this Mar 22, 2018
@lock
Copy link

lock bot commented May 31, 2018

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators May 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants