Anonymous users
Many apps let people start writing before they make an account, or let a visitor who opened a shared link comment without signing up. Proof doesn’t mind who your users are, only that you give each one an id of yours, so an anonymous visitor is just another user to Proof. By the end of this guide, visitors can write straight away, and everything they did moves to their account when they sign up.
Give visitors a user
Section titled “Give visitors a user”-
Make an id when a visitor first needs one, such as when they start a document or open a shared link, and keep it in your own session. It becomes the user’s
external_idat Proof. Any string up to 128 characters works; a prefix makes these easy to spot.session.ts async function currentUser(req) {if (req.user) return req.user;if (!req.session.anonymousId) {req.session.anonymousId = `anon_${crypto.randomUUID()}`;req.session.anonymousName = randomName(); // "Brisk Heron"}return { id: req.session.anonymousId, name: req.session.anonymousName, anonymous: true };} -
Create the user in Proof with a name that reads well in the margin and in comments, and keep the Proof id in the session beside your own. A made-up name is friendlier than “Anonymous”, and lets people tell two visitors apart.
const visitor = await currentUser(req);if (!req.session.proofUserId) {const proofUser = await proof.users.upsert(visitor.id, { name: visitor.name });req.session.proofUserId = proofUser.id;} -
Use them like any other user. Create documents they own, start editor sessions, and start link sessions for shared documents. Everything they write is credited to their made-up name.
Anonymous users can do everything signed-in users can in Proof: write, comment, add security keys, connect agents and seal. Which of those your app allows before sign-up is up to you.
Merge when they sign up
Section titled “Merge when they sign up”When a visitor signs up or signs in, merge their anonymous user into their account:
app.post("/sign-in/complete", async (req, res) => { const account = await finishSignIn(req); // your own sign-in
if (req.session.proofUserId) { // proofUserId: the helper from Embed the editor, which creates the account's Proof user if needed. await proof.users.merge(req.session.proofUserId, { into: await proofUserId(account) }); delete req.session.anonymousId; delete req.session.proofUserId; } res.redirect("/notes");});Merging moves, from the anonymous user to the account:
- Documents and memberships. Where both were members of the same document, the account keeps the higher role.
- Credit. Everything the visitor wrote, commented and suggested now shows under the account’s name, in open editors too.
- Security keys and their check-ins, and the check-in interval unless the account already has one.
- Agents, still reaching the same documents. One for a client the account already connected joins that agent.
The anonymous user is then gone: its Proof id answers 404, and its external_id is free. Existing seals keep the name they were sealed with, as seals always do.
Merge before you start the next editor session. An editor still open as the anonymous user loses its session when the merge completes and asks your page for a new token; once your session route starts sessions as the account, it picks up where it left off.
Clean up visitors who never come back
Section titled “Clean up visitors who never come back”Anonymous users stay until you delete them. Proof of Thought removes anonymous accounts 30 days after their last visit, by the Proof id it kept for each:
await proof.users.delete("usr_2Hd7Np4Q");Deleting a user deletes documents nobody else is a member of or wrote in, with their seals. In documents shared with others, what the visitor wrote keeps the name they last had, without a picture.