# Omit the user from shared links

**URL:** <https://racket.discourse.group/t/omit-the-user-from-shared-links/1221>\
**Category:** Site Feedback\
**Tags:** link, share, user\
**Created:** [August 10, 2022, 10:22pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221 "2022-08-10T22:22:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [August 10, 2022, 10:22pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221/1 "2022-08-10T22:22:16Z")

</div>

The sharing links that Discourse (or this Discourse instance?) uses all seem to have the user id appended as a query parameter. For example, if I go to the [Racket 8.6 release thread](https://racket.discourse.group/t/racket-v8-6-release-thread/1091) and click on the link symbol of the first post, I get the link

```scheme
https://racket.discourse.group/t/racket-v8-6-release-thread/1091?u=sschwarzer

```

What I would like to get instead is

```scheme
https://racket.discourse.group/t/racket-v8-6-release-thread/1091

```

Is it possible to switch off the addition of the user name? I don't think it's that useful to know who copied the link originally, especially if the link is forwarded further.

At the moment, my workaround is to remove the `?u=sschwarzer` manually.

---

<div class="post-metadata">

**Author:** ![simonls](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/simonls/32/170_2.png) [@simonls](https://racket.discourse.group/u/simonls)\
**Post date:** [August 10, 2022, 11:14pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221/2 "2022-08-10T23:14:17Z")

</div>

I don't have a strong opinion on this topic.  
Here are two posts on the meta site that I found on the topic:

> **[Why do all shared links include the username (u=username)](https://meta.discourse.org/t/why-do-all-shared-links-include-the-username-u-username/60126)**
>
> What exactly is the reason that every link to a discourse post has a u=username at the end? Since the links are functional without, I suppose the idea is some sort of tracking. But for what purpose and where/how does they become tangible in some...

> **[Usernames in shared links break anonymity](https://meta.discourse.org/t/usernames-in-shared-links-break-anonymity/42554)**
>
> Most forums operate with a level of user anonymity - usernames are used instead of real names. The social sharing functions of Discourse however show the username in an unecrypted format, such as: ...

This post from the second topic seems to suggest that they would be open to a feature being added as a PR (In other posts they say that no paying customer has wanted it):

> **[Usernames in shared links break anonymity](https://meta.discourse.org/t/usernames-in-shared-links-break-anonymity/42554/9)**
>
> I am fine with that as a PR, but you would automatically lose all the sharing badges (first share, nice share, good share, great share) if you disabled usernames there.

Having it as a global site setting seems too much, because different users would probably prefer it differently. Personally I think there should be a user setting to disable it, maybe that could be added via PR.

Alternatively it might be possible to create a browser local user script with some extension like [https://www.tampermonkey.net/](https://www.tampermonkey.net/) ~~but I guess that is more of a last resort solution, if no PR would be accepted~~.

Also I am not sure what settings there are, I haven't explored that in depth.

* * *

~~Considering that it is quite easy to write that script maybe it is a good solution and~~ the good thing about it is that you can even customize it to your liking and different users can make it do what they want, I haven't tested it extensively, ~~but it seems to work~~ (almost):

It works the first time, after that it always shows the rewritten text from the first opening even for other posts, but I am currently too tired to figure out why / what kind of state keeps hanging around, or if it somehow blocks some code from setting the new value...  
I guess I hate working with the DOM, too much state and stuff and no way to sensibly compose programs, or easily find out how one thing breaks some other code.  
Maybe someone else finds the solution, I don't want to waste any more time on this...

```javascript
// ==UserScript==
// @name share link username remover
// @namespace http://tampermonkey.net/
// @version 0.1
// @description removes the username from sharelink on discourse websites
// @author You
// @match *.discourse.group/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=discourse.group
// @grant none
// ==/UserScript==

(function() {
    'use strict';

    let container = document.querySelector("#discourse-modal");
    new MutationObserver(function() {
        if(container.classList.contains("hidden")) {
            container.removeAttribute("removed-username"); // reset the class
        } else if(!container.getAttribute("removed-username")) {
            // only remove the username once per opening of the modal
            let node = document.querySelector(".link-share-container .invite-link");
            let url = new URL(node.value);
            url.search = "";
            let new_value = url.toString();
            node.value = new_value
            // reselect all the text
            node.setSelectionRange(0, new_value.length);
            container.setAttribute("removed-username","true");
        }
    }).observe(container, {"attributes":true, "attributeFilter":["class"]});
    // uses attributeFilter to avoid infinite mutation observation loops
    // where after observation we generate the next mutation

})();

```

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [August 11, 2022, 12:56pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221/3 "2022-08-11T12:56:48Z")

</div>

> I don't have a strong opinion on this topic.

I do have a strong opinion: The best default value for anything is whatever tends to preserve privacy and/or minimize future interactions. People should explicitly opt in to identity disclosures, tracking, notifications, etc.

However it seems N/A for me in this case:

- I usually copy the URL from the browser address bar (I just don't love site "share" buttons).

- I review the URL to cleanse and simplify:

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [August 11, 2022, 1:57pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221/4 "2022-08-11T13:57:45Z")

</div>

> [@greghendershott](#):
>
> I do have a strong opinion: The best default value for anything is whatever tends to preserve privacy and/or minimize future interactions. People should explicitly opt in to identity disclosures, tracking, notifications, etc.

Well said! 🙂

> [@greghendershott](#):
>
> I usually copy the URL from the browser address bar (I just don't love site "share" buttons).

I do that if I want to link to a discussion thread as a whole, but I use the "share" link when I want to link to a specific post in the thread.

> [@greghendershott](#):
>
> I review the URL to cleanse and simplify:

I usually do this, too, but it would be nice if I didn't have to. 😉

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [August 11, 2022, 2:06pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221/5 "2022-08-11T14:06:17Z")

</div>

I've discovered that for all the sites I use, there is usually some link on each comment/post -- usually with its datetime -- where I can right click and choose Copy Link. Then the usual paste + cleanup.

On Discourse it's at the top of each post, on the same line as the user name, right-aligned. e.g. "6m" or "3h" or "2d" or "Jul 7".

Something similar on Slack, GitHub issues, and so on.

* * *

Having said that, I agree 100% that Discourse should have an option to exclude this. With what we agree is the proper default. 😄

Then you really could just trust and use the share button.

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [August 11, 2022, 8:00pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221/6 "2022-08-11T20:00:05Z")

</div>

> [@sschwarzer](#):
>
> > [@greghendershott](#):
> >
> > I do have a strong opinion: The best default value for anything is whatever tends to preserve privacy and/or minimize future interactions. People should explicitly opt in to identity disclosures, tracking, notifications, etc.
> 
> Well said! 🙂

I definitely agree with this in general. The Discourse shared links bother me less than many things because they seem reasonably transparent about what they're doing. When I click on the share button, I see something like this:

 ![Screenshot 2022-08-11 at 15-44-36 Omit the user from shared links - Site Feedback - Racket Discussions](https://global.discourse-cdn.com/free1/uploads/racket/original/1X/1fa7132b1c899b8374decb57b337f8f50cfb4f65.png)

The actual URL is displayed in the UI; the one and only query parameter is my user name, so it's clear exactly what information it is I'd be disclosing; and the text box is even scrolled to the right, so that the query parameter is visible.

Nonetheless, I usually remove the query parameter, and I'd be glad to have a setting to do so by default. (The Racket documentation search parameters also helped reinforce this habit for me!) Just, if people, generally, were to find the sharing-related badges fun or whatever (I don't know if that's the case!), I wouldn't be especially bothered about the default value for this particular standing.

* * *

Tangentially, if you want a short link to share, you can also remove the name and just use e.g. `https://racket.discourse.group/t/1221/3`.

---

<div class="post-metadata">

**Author:** ![simonls](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/simonls/32/170_2.png) [@simonls](https://racket.discourse.group/u/simonls)\
**Post date:** [August 11, 2022, 9:00pm UTC](https://racket.discourse.group/t/omit-the-user-from-shared-links/1221/7 "2022-08-11T21:00:09Z")

</div>

I noticed something interesting, as you scroll through the posts, discourse updates the current url to have the number of the post that is currently at the top of the screen.

So scrolling to the wanted post and then using a browser keyboard shortcut to copy the current url would work too.

> [@greghendershott](#):
>
> On Discourse it's at the top of each post, on the same line as the user name, right-aligned. e.g. "6m" or "3h" or "2d" or "Jul 7".

This gave me the idea to change the user script to manipulate that number link, so that it just copies the link to the clipboard without opening a modal window. I like that idea because that link in itself isn't that useful anyway and this way you can still access the modal window through the share button, but use the minutes as a copy uri to clipboard shortcut.

I think I will actually use this version because it allows me to avoid needing multiple clicks.  
It suppresses the original event, to prevent the modal from opening, sadly because of this you also lose the proper aligned scrolling of the post to the top and the blink/fade effect, but considering that this happens on page load automatically maybe it doesn't matter.

Instead I added a custom animation so that there is some kind of visual feedback, (if you use light mode) you need to change the colors to your liking.

```javascript
// ==UserScript==
// @name share link username remover
// @namespace http://tampermonkey.net/
// @version 0.1
// @description removes the username from sharelink on discourse websites
// @author You
// @match *.discourse.group/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=discourse.group
// @grant none
// ==/UserScript==

(function() {
    'use strict';

    const dummy_base = "rel://rel.rel";
    const dummy_len = dummy_base.length;
    const remove_username_rel = (s) => {
        const url = new URL(s, dummy_base);
        url.search = "";
        return url.toString().substring(dummy_len);
    };
    const update_attribute = (node, attr, update) => {node.setAttribute(attr, update(node.getAttribute(attr)))};
    const copy_animation = [
        {backgroundColor:"#222"},
        {backgroundColor:"#3cbd21"},
        {backgroundColor:"#222"}
    ];
    const save_link_to_clipboard = (event) => {
        window.navigator.clipboard.writeText(origin + event.currentTarget.getAttribute("href"));
        event.preventDefault();
        event.stopPropagation();
        event.currentTarget.closest(".topic-body").animate(copy_animation, {duration:500, iterations:1});
    };
    const add_click_handler = (node) => {
        node.classList.remove("widget-link");
        update_attribute(node, "href", remove_username_rel);
        node.addEventListener("click", save_link_to_clipboard, true);
    };

    const state = {running:false};
    const remove_usernames = () => {
        if(state.running)return;
        state.running = true;
        const dateLinks = document.querySelectorAll(".topic-post .post-date a");
        for(let l of dateLinks) add_click_handler(l);
        state.running = false;
    };

    const username_remover = new MutationObserver(remove_usernames);
    username_remover.observe(document.querySelector("#topic"), {childList:true, subtree:true});
    remove_usernames();

})();

```
