-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
feat: $props.id(), a SSR-safe ID generation #15185
Conversation
Merge
🦋 Changeset detectedLatest commit: adbcbd7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
I like this, but I'm not sure if it should just be a function imported from the <script>
import {createUID} from 'svelte';
let uid = createUID();
</script> However, I also don't think it should be a rune, as not everything should be a rune; in my opinion, if it can be easily recreated while still writing less code, it doesn't need to be a rune. |
This should be either a rune or regular function - not sure which one makes more sense. I lean towards function. |
A regular function may not be possible, as it need to generate an hydration comment. So do I adapt it into a rune ? $uid(); // return "s100"
$uid('title'); // return "s100-title" |
I'm not sure if it should be an independent rune, or if a rune called like |
What about |
Yes an <script>
const uid = $props.id();
</script>
<label for="{uid}-firstname">First Name: </label>
<input type="text" id="{uid}-firstname" />
<label for="{uid}-lastname">Last Name: </label>
<input type="text" id="{uid}-lastname" /> I will try to implement it |
Demo here : REPL The following code : <script>
const uid = $props.id();
</script> Will be compiled to something like that in server-side : const uid = $.props_id($$payload); The function On client-side, this code will be compiled as : const uid = $.props_id(); The function |
Why start in 100? Start with 1. Less characters, less bytes to transfer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
made some small tweaks and added some docs and I think this is ready to go. Thank you @adiguba! Great feature
Nice ! |
It seems like this can only be used within the components code. Lets say i want to build a class within |
No you cannot use it on *.svelte.js But you can just pass it as param : // select.svelte.js
export function init(uid) {
...
} <script>
import { init } from './select.svelte.js'
const uid = $props.id();
init(uid);
</script> |
I just added a small example code in the doc... |
|
||
## `$props.id()` | ||
|
||
This rune, added in version 5.20.0, generates an ID that is unique to the current component instance. When hydrating a server-rendered a component, the value will be consistent between server and client. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- When hydrating a server-rendered a component
+ When hydrating a server-rendered component
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed the change.
But I'm not sure if it's the correct way to accept the contribution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good, just noticed it. Thanks for updating it 👍
packages/svelte/src/ambient.d.ts
Outdated
@@ -339,6 +339,15 @@ declare namespace $effect { | |||
declare function $props(): any; | |||
|
|||
declare namespace $props { | |||
/** | |||
* Generates an ID that is unique to the current component instance. When hydrating a server-rendered a component, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
Just realised we never merged/released this, oops! Happening now. Thanks @adiguba |
Wow, fantastic job on this! It's all well communicated and considered, with a nice useful scope, good docs, and it's also just a simple to understand feature. 👏🙌 |
Great feature! One minor downside for DX: it's no longer possible to assign const props: AccordionRootProps = $props() // No longer possible
const id = $props.id() const rootProps: AccordionRootProps = $props() // Works
const id = $props.id() |
This code works at runtime...the error should just be from the language server but that's already been fixed (we just need to release the new version) |
A work and progress implementation for #7517 (SSR-safe ID generation)
It introduce a new constant
$$uid
, unique for each instance of a component, based on this comment from dummdidumm (edit: sorry for the tag on sunday : it was not intentional) : #7517 (comment)The id will be generated by a simple counter, prefixed by
s
on server side, andc
on client side in order to avoid conflict.On server side, a comment like
<!--#s100-->
will be generated in order to "pass" the ID for hydrating the client.Note :
$uid()
would be more appropriate.$$uid
can be used in asvelte.js/ts
file, but this causes an error at runtime. I don't known how to handle this...Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.packages/svelte/src
, add a changeset (npx changeset
).Tests and linting
pnpm test
and lint the project withpnpm lint