Using a non-conforming doctype with Vite
Using a fresh install of Vite via npm create vite@latest
we get the following index.html
. Note the modern doctype.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
MDN
<!DOCTYPE html>
is the simplest possible, and the one recommended by current HTML standards.
I naively assumed I could change the doctype and continue development without issue.
<!DOCTYPE html PUBLIC "-//HbbTV//1.3.1//EN" "http://www.hbbtv.org/dtd/HbbTV-1.3.1.dtd">
<html lang="en">
<!-- ... -->
</html>
However, doing this throws an error non-conforming-doctype
.
ERROR 10:31:16 [vite] Internal server error: Unable to parse HTML; parse5 error code non-conforming-doctype at /path/to/file/index.html:1:1
1 | <!DOCTYPE html PUBLIC "-//HbbTV//1.3.1//EN" "http://www.hbbtv.org/dtd/HbbTV-1.3.1.dtd">
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This issue happens as the parse5 library, which Vite uses for HTML parsing, expects a valid and conforming doctype declaration at the top of the HTML file. If the doctype declaration is missing, incorrect, or non-standard, it can throw this error.
Solution
One solution is to use transformIndexHtml
which requires a little bit of configuration in the vite.config.js
file; if you don’t already have one create it in the root of the project.
Using transformIndexHtml
transformIndexHtml
is a Vite specific hook used to transform the index.html
file. We can use this to replace the doctype after the html has been processed.
import { defineConfig } from "vite";
export default defineConfig({
plugins: [
{
name: "html-transform",
transformIndexHtml: (html) => {
return html.replace(
"<!DOCTYPE html>",
'<!DOCTYPE html PUBLIC "-//HbbTV//1.3.1//EN" "http://www.hbbtv.org/dtd/HbbTV-1.3.1.dtd">'
);
},
},
],
});
Now run the build and check the source of index.html
, note that the doctype has been replaced.
<!DOCTYPE html PUBLIC "-//HbbTV//1.3.1//EN" "http://www.hbbtv.org/dtd/HbbTV-1.3.1.dtd">
<html lang="en">
<!-- ... -->
</html>