lit / lit

Lit is a simple library for building fast, lightweight web components.
https://lit.dev
BSD 3-Clause "New" or "Revised" License
18.52k stars 914 forks source link

[@lit-labs/ssr, @lit-labs/nextjs] SSR breaks with svg title tag #4405

Open kyubisation opened 10 months ago

kyubisation commented 10 months ago

Which package(s) are affected?

React (@lit/react), SSR (@lit-labs/ssr)

Description

When using svg`<title>${this.name}</title>` inside render() in an enclosing html template with an svg, it causes an error. It also breaks with html`<p>Hello <svg><title>${this.name}</title></svg></p>`.

Error: 
    Unexpected final partIndex: 0 !== 1 while processing the following template:

    <title>${...}</title>

    This could be because you're attempting to render an expression in an invalid location. See
    https://lit.dev/docs/templates/expressions/#invalid-locations for more information about invalid expression
    locations.

    at throwErrorForPartIndexMismatch (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit-labs/ssr/lib/render-value.js:620:11)
    at renderTemplateResult (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit-labs/ssr/lib/render-value.js:607:9)
    at renderValue (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit-labs/ssr/lib/render-value.js:419:16)
    at renderTemplateResult (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit-labs/ssr/lib/render-value.js:486:24)
    at Module.renderValue (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit-labs/ssr/lib/render-value.js:419:16)
    at LitElementRenderer.renderShadow (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit-labs/ssr/lib/lit-element-renderer.js:84:33)
    at Object.litPatchedCreateElement (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit-labs/ssr-react/lib/node/wrap-create-element.js:38:37)
    at eval (/home/projects/stackblitz-starters-ggktnm/node_modules/@lit/react/node/create-component.js:19:456)
    at renderWithHooks (/home/projects/stackblitz-starters-ggktnm/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5658:16)
    at renderForwardRef (/home/projects/stackblitz-starters-ggktnm/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5842:18) {
  page: '/'
}

Reproduction

https://stackblitz.com/edit/stackblitz-starters-ggktnm?file=components%2Fsimple-greeting.ts

Start with npm install && npx next dev and the error should be shown in console (after build) and in the preview window.

Workaround

Replacing svg`<title>${this.name}</title>` with svg`<title>text</title>` works, but that is not an actual workaround.

Is this a regression?

No or unsure. This never worked, or I haven't tried before.

Affected versions

lit 3.1.0, @lit/react 1.0.1, @lit-labs/nextjs 0.1.4

Browser/OS/Node environment

Browser: - OS: Linux Node.js: v18.18.0 npm: 9.4.2

AndrewJakubowicz commented 10 months ago

I think this is a known issue in lit-labs/ssr. I think the current theory is that SSR confuses the svg <title> for the HTML <title>. And the HTML <title> tag is an invalid dynamic location during SSR (unless using a server template).

You can workaround your issue by using unsafeSVG imported from lit/directives/unsafe-svg.js. This tells SSR to trust the title svg element that you're inserting.

import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
// ...
html`<svg>${unsafeSVG(`<title>${this.name}</title>`)}</svg>`

See working stackblitz example: https://stackblitz.com/edit/stackblitz-starters-tpsg7w?file=components%2Fsimple-greeting.ts

However keeping issue open because ideally you shouldn't need a workaround. Thank you for the report.

kyubisation commented 10 months ago

Thanks for the quick answer and workaround. I'll try it out.

kyubisation commented 9 months ago

In this specific instance, I was able to solve it via <title .textContent=${variable}></title>.