Repository: sveltejs/svelte (JavaScript)
Date: 2021-12-28 11:43:19+00:00
Task type: Bug Fix

Issue:
Wrong server-side rendering of attributes when value is `true`
**Describe the bug**
When passing a `true` value to a custom data attribute (e.g. `data-active`) in SSR, it renders `data-active=""`.

**To Reproduce**
```svelte
<script>
	let content = true;
</script>

<div data-active={content}></div>
```

**Expected behavior**
I'm only expecting an attribute to be rendered as `attr=""` when the value passed to it is `true` if it's a boolean attribute. In the case of any other attribute, `attr="true"` should be rendered instead (as it is when using DOM rendering).

**Stacktraces**
It's easy to see the origin of the problem, at https://github.com/sveltejs/svelte/blob/master/src/runtime/internal/ssr.ts#L130-L133

**Severity**
Annoying, particularly because of the inconsistency for such attributes between SSR and DOM rendering. For now we're writing things like `data-active={value === true ? 'true' : false}` as a workaround.

I can open a PR to fix this behavior if it's ok for you :)


Issue discussion:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

I can confirm we are affected by this at @huggingface
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

unstale, and cc'ing @pngwn on this =)
> I can open a PR to fix this behavior if it's ok for you :)

Yes feel free to open a PR

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## Unreleased
 
+* Fix non-boolean attribute rendering in SSR to render truthy values as-is ([#6121](https://github.com/sveltejs/svelte/issues/6121))
 * Add `a11y-no-redundant-roles` warning ([#7067](https://github.com/sveltejs/svelte/pull/7067))
 
 ## 3.44.3
diff --git a/src/runtime/internal/ssr.ts b/src/runtime/internal/ssr.ts
--- a/src/runtime/internal/ssr.ts
+++ b/src/runtime/internal/ssr.ts
@@ -141,7 +141,7 @@ export function create_ssr_component(fn) {
 
 export function add_attribute(name, value, boolean) {
 	if (value == null || (boolean && !value)) return '';
-	return ` ${name}${value === true ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `"${value}"`}`}`;
+	return ` ${name}${value === true && boolean_attributes.has(name) ? '' : `=${typeof value === 'string' ? JSON.stringify(escape(value)) : `"${value}"`}`}`;
 }
 
 export function add_classes(classes) {


Test patch:
diff --git a/test/runtime/samples/attribute-boolean-true/_config.js b/test/runtime/samples/attribute-boolean-true/_config.js
--- a/test/runtime/samples/attribute-boolean-true/_config.js
+++ b/test/runtime/samples/attribute-boolean-true/_config.js
@@ -1,7 +1,8 @@
 export default {
-	html: '<textarea readonly></textarea>',
+	html: '<textarea readonly data-attr="true"></textarea>',
 	test({ assert, target }) {
 		const textarea = target.querySelector('textarea');
+		assert.equal(textarea.dataset.attr, 'true');
 		assert.ok(textarea.readOnly);
 	}
 };
diff --git a/test/runtime/samples/attribute-boolean-true/main.svelte b/test/runtime/samples/attribute-boolean-true/main.svelte
--- a/test/runtime/samples/attribute-boolean-true/main.svelte
+++ b/test/runtime/samples/attribute-boolean-true/main.svelte
@@ -1 +1 @@
-<textarea readonly="{true}"></textarea>
\ No newline at end of file
+<textarea readonly={true} data-attr={true} />