diff --git a/README.md b/README.md
index eb792491..0db25be3 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,7 @@ Allowed values are as follows
|**[`templateParameters`](#)**|`{Boolean\|Object\|Function}`|``| Allows to overwrite the parameters used in the template |
|**[`inject`](#)**|`{Boolean\|String}`|`true`|`true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `true` or `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element|
|**[`favicon`](#)**|`{String}`|``|Adds the given favicon path to the output HTML|
+|**[`meta`](#)**|`{Object}`|`{}`|Allows to inject `meta`-tags. E.g. `meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}`|
|**[`minify`](#)**|`{Boolean\|Object}`|`true`|Pass [html-minifier](https://github.com/kangax/html-minifier#options-quick-reference)'s options as object to minify the output|
|**[`hash`](#)**|`{Boolean}`|`false`|If `true` then append a unique `webpack` compilation hash to all included scripts and CSS files. This is useful for cache busting|
|**[`cache`](#)**|`{Boolean}`|`true`|Emit the file only if it was changed|
diff --git a/index.js b/index.js
index d7844eaf..a826f276 100644
--- a/index.js
+++ b/index.js
@@ -30,6 +30,7 @@ class HtmlWebpackPlugin {
showErrors: true,
chunks: 'all',
excludeChunks: [],
+ meta: {},
title: 'Webpack App',
xhtml: false
}, options);
@@ -179,7 +180,7 @@ class HtmlWebpackPlugin {
const html = result.html;
const assets = result.assets;
// Prepare script and link tags
- const assetTags = self.generateAssetTags(assets);
+ const assetTags = self.generateHtmlTags(assets);
const pluginArgs = {head: assetTags.head, body: assetTags.body, plugin: self, chunks: chunks, outputName: self.childCompilationOutputName};
// Allow plugins to change the assetTag definitions
return applyPluginsAsyncWaterfall('html-webpack-plugin-alter-asset-tags', true, pluginArgs)
@@ -482,15 +483,44 @@ class HtmlWebpackPlugin {
return assets;
}
+ /**
+ * Generate meta tags
+ */
+ getMetaTags () {
+ if (this.options.meta === false) {
+ return [];
+ }
+ // Make tags self-closing in case of xhtml
+ // Turn { "viewport" : "width=500, initial-scale=1" } into
+ // [{ name:"viewport" content:"width=500, initial-scale=1" }]
+ const selfClosingTag = !!this.options.xhtml;
+ const metaTagAttributeObjects = Object.keys(this.options.meta).map((metaName) => {
+ const metaTagContent = this.options.meta[metaName];
+ return (typeof metaTagContent === 'object') ? metaTagContent : {
+ name: metaName,
+ content: metaTagContent
+ };
+ });
+ // Turn [{ name:"viewport" content:"width=500, initial-scale=1" }] into
+ // the html-webpack-plugin tag structure
+ return metaTagAttributeObjects.map((metaTagAttributes) => {
+ return {
+ tagName: 'meta',
+ voidTag: true,
+ selfClosingTag: selfClosingTag,
+ attributes: metaTagAttributes
+ };
+ });
+ }
+
/**
* Injects the assets into the given html string
*/
- generateAssetTags (assets) {
+ generateHtmlTags (assets) {
// Turn script files into script tags
const scripts = assets.js.map(scriptPath => ({
tagName: 'script',
closeTag: true,
-
attributes: {
type: 'text/javascript',
src: scriptPath
@@ -502,14 +532,14 @@ class HtmlWebpackPlugin {
const styles = assets.css.map(stylePath => ({
tagName: 'link',
selfClosingTag: selfClosingTag,
-
+ voidTag: true,
attributes: {
href: stylePath,
rel: 'stylesheet'
}
}));
// Injection targets
- let head = [];
+ let head = this.getMetaTags();
let body = [];
// If there is a favicon present, add it to the head
@@ -517,6 +547,7 @@ class HtmlWebpackPlugin {
head.push({
tagName: 'link',
selfClosingTag: selfClosingTag,
+ voidTag: true,
attributes: {
rel: 'shortcut icon',
href: assets.favicon
@@ -541,8 +572,8 @@ class HtmlWebpackPlugin {
const htmlRegExp = /(]*>)/i;
const headRegExp = /(<\/head\s*>)/i;
const bodyRegExp = /(<\/body\s*>)/i;
- const body = assetTags.body.map(this.createHtmlTag);
- const head = assetTags.head.map(this.createHtmlTag);
+ const body = assetTags.body.map(this.createHtmlTag.bind(this));
+ const head = assetTags.head.map(this.createHtmlTag.bind(this));
if (body.length) {
if (bodyRegExp.test(html)) {
diff --git a/spec/BasicSpec.js b/spec/BasicSpec.js
index ca0d5158..a5b5861a 100644
--- a/spec/BasicSpec.js
+++ b/spec/BasicSpec.js
@@ -1300,6 +1300,43 @@ describe('HtmlWebpackPlugin', function () {
}, [//], null, done);
});
+ it('adds a meta tag', function (done) {
+ testHtmlPlugin({
+ entry: path.join(__dirname, 'fixtures/index.js'),
+ output: {
+ path: OUTPUT_DIR,
+ filename: 'index_bundle.js'
+ },
+ plugins: [
+ new HtmlWebpackPlugin({
+ meta: {
+ 'viewport': {
+ 'name': 'viewport',
+ 'content': 'width=device-width, initial-scale=1, shrink-to-fit=no'
+ }
+ }
+ })
+ ]
+ }, [//], null, done);
+ });
+
+ it('adds a meta tag with short notation', function (done) {
+ testHtmlPlugin({
+ entry: path.join(__dirname, 'fixtures/index.js'),
+ output: {
+ path: OUTPUT_DIR,
+ filename: 'index_bundle.js'
+ },
+ plugins: [
+ new HtmlWebpackPlugin({
+ meta: {
+ 'viewport': 'width=device-width, initial-scale=1, shrink-to-fit=no'
+ }
+ })
+ ]
+ }, [//], null, done);
+ });
+
it('adds a favicon with publicPath set to /some/', function (done) {
testHtmlPlugin({
entry: path.join(__dirname, 'fixtures/index.js'),