From 2aa64c075d42ca402b9bcbafe4fc5ecf8cfb9c89 Mon Sep 17 00:00:00 2001 From: Colby Gutierrez-Kraybill <colby+github@kraybill.com> Date: Fri, 18 Apr 2025 18:28:05 -0400 Subject: [PATCH] hrefs for /users/:username without a trailing / lead to django kicking back a redirect to /users/:username/ This activity leads to scratch-www-production having 40-60% redirects. It would be useful to clear this noise up for SRE related operations. --- .../become-a-scratcher/become-a-scratcher.jsx | 2 +- src/views/contact-us/contact-us.jsx | 2 +- .../messages/message-rows/comment-message.jsx | 2 +- .../message-rows/favorite-project.jsx | 2 +- .../messages/message-rows/love-project.jsx | 2 +- .../messages/message-rows/remix-project.jsx | 2 +- .../splash/activity-rows/favorite-project.jsx | 2 +- .../splash/activity-rows/remix-project.jsx | 2 +- .../splash/activity-rows/share-project.jsx | 2 +- src/views/studio/studio-activity.jsx | 24 +++++++++---------- src/views/studio/studio-member-tile.jsx | 2 +- src/views/studio/studio-project-tile.jsx | 2 +- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/views/become-a-scratcher/become-a-scratcher.jsx b/src/views/become-a-scratcher/become-a-scratcher.jsx index 6c93c29c4..42db63607 100644 --- a/src/views/become-a-scratcher/become-a-scratcher.jsx +++ b/src/views/become-a-scratcher/become-a-scratcher.jsx @@ -67,7 +67,7 @@ const OnboardingHeader = ({user, section, secondary}) => { className="profile-page-image" src="/images/onboarding/profile-page-become-a-scratcher-button.svg" /> - <a href={`/users/${user.username}`}> + <a href={`/users/${user.username}/`}> <Button> <FormattedMessage id={'becomeAScratcher.buttons.backToProfile'} diff --git a/src/views/contact-us/contact-us.jsx b/src/views/contact-us/contact-us.jsx index 9e022e4cf..59e9d5667 100644 --- a/src/views/contact-us/contact-us.jsx +++ b/src/views/contact-us/contact-us.jsx @@ -31,7 +31,7 @@ class ContactUs extends React.Component { } else if (query.indexOf('profile=') !== -1) { scratchId = query.match(/profile=([a-zA-Z0-9-_]+)/)[1]; this.state.subject = `Issue reported with profile ${scratchId}`; - this.state.body = `https://scratch.mit.edu/users/${scratchId}`; + this.state.body = `https://scratch.mit.edu/users/${scratchId}/`; } else if (query.indexOf('confirmation=') !== -1) { this.state.subject = 'Problem with email confirmation'; } diff --git a/src/views/messages/message-rows/comment-message.jsx b/src/views/messages/message-rows/comment-message.jsx index 0d4f91966..1f36cff50 100644 --- a/src/views/messages/message-rows/comment-message.jsx +++ b/src/views/messages/message-rows/comment-message.jsx @@ -161,7 +161,7 @@ class CommentMessage extends React.Component { {this.getMessageText(this.props.objectType, this.props.commentee)} </p> <FlexRow className="mod-comment-message"> - <a href={`/users/${this.props.actorUsername}`}> + <a href={`/users/${this.props.actorUsername}/`}> <img alt={`${this.props.actorUsername}'s avatar`} className="comment-message-info-img" diff --git a/src/views/messages/message-rows/favorite-project.jsx b/src/views/messages/message-rows/favorite-project.jsx index b75534eaf..48e488e56 100644 --- a/src/views/messages/message-rows/favorite-project.jsx +++ b/src/views/messages/message-rows/favorite-project.jsx @@ -21,7 +21,7 @@ const FavoriteProjectMessage = props => ( profileLink: ( <a className="social-messages-profile-link" - href={`/users/${props.actorUsername}`} + href={`/users/${props.actorUsername}/`} > {props.actorUsername} </a> diff --git a/src/views/messages/message-rows/love-project.jsx b/src/views/messages/message-rows/love-project.jsx index 3d5409aff..8d154e819 100644 --- a/src/views/messages/message-rows/love-project.jsx +++ b/src/views/messages/message-rows/love-project.jsx @@ -21,7 +21,7 @@ const LoveProjectMessage = props => ( profileLink: ( <a className="social-messages-profile-link" - href={`/users/${props.actorUsername}`} + href={`/users/${props.actorUsername}/`} > {props.actorUsername} </a> diff --git a/src/views/messages/message-rows/remix-project.jsx b/src/views/messages/message-rows/remix-project.jsx index 356e6f6b5..c0639b4c2 100644 --- a/src/views/messages/message-rows/remix-project.jsx +++ b/src/views/messages/message-rows/remix-project.jsx @@ -21,7 +21,7 @@ const RemixProjectMessage = props => ( profileLink: ( <a className="social-messages-profile-link" - href={`/users/${props.actorUsername}`} + href={`/users/${props.actorUsername}/`} > {props.actorUsername} </a> diff --git a/src/views/splash/activity-rows/favorite-project.jsx b/src/views/splash/activity-rows/favorite-project.jsx index 8775fd024..e7b073658 100644 --- a/src/views/splash/activity-rows/favorite-project.jsx +++ b/src/views/splash/activity-rows/favorite-project.jsx @@ -18,7 +18,7 @@ const FavoriteProjectMessage = props => ( id="messages.favoriteText" values={{ profileLink: ( - <a href={`/users/${props.actorUsername}`}> + <a href={`/users/${props.actorUsername}/`}> {props.actorUsername} </a> ), diff --git a/src/views/splash/activity-rows/remix-project.jsx b/src/views/splash/activity-rows/remix-project.jsx index 67b8b1f4b..160008d6a 100644 --- a/src/views/splash/activity-rows/remix-project.jsx +++ b/src/views/splash/activity-rows/remix-project.jsx @@ -18,7 +18,7 @@ const RemixProjectMessage = props => ( id="messages.remixText" values={{ profileLink: ( - <a href={`/users/${props.actorUsername}`}> + <a href={`/users/${props.actorUsername}/`}> {props.actorUsername} </a> ), diff --git a/src/views/splash/activity-rows/share-project.jsx b/src/views/splash/activity-rows/share-project.jsx index 71ed56ef1..786e91c67 100644 --- a/src/views/splash/activity-rows/share-project.jsx +++ b/src/views/splash/activity-rows/share-project.jsx @@ -18,7 +18,7 @@ const ShareProjectMessage = props => ( id="messages.shareText" values={{ profileLink: ( - <a href={`/users/${props.actorUsername}`}> + <a href={`/users/${props.actorUsername}/`}> {props.actorUsername} </a> ), diff --git a/src/views/studio/studio-activity.jsx b/src/views/studio/studio-activity.jsx index 9a17377a7..8fd608cd1 100644 --- a/src/views/studio/studio-activity.jsx +++ b/src/views/studio/studio-activity.jsx @@ -27,7 +27,7 @@ const getComponentForItem = item => { id="studio.activityAddProjectToStudio" values={{ profileLink: ( - <a href={`/users/${item.actor_username}`}> + <a href={`/users/${item.actor_username}/`}> {item.actor_username} </a> ), @@ -53,7 +53,7 @@ const getComponentForItem = item => { id="studio.activityRemoveProjectStudio" values={{ profileLink: ( - <a href={`/users/${item.actor_username}`}> + <a href={`/users/${item.actor_username}/`}> {item.actor_username} </a> ), @@ -79,7 +79,7 @@ const getComponentForItem = item => { id="studio.activityUpdateStudio" values={{ profileLink: ( - <a href={`/users/${item.actor_username}`}> + <a href={`/users/${item.actor_username}/`}> {item.actor_username} </a> ) @@ -101,12 +101,12 @@ const getComponentForItem = item => { values={{ // Beware, DB seems to think actor is new curator and username is inviter newCuratorProfileLink: ( - <a href={`/users/${item.actor_username}`}> + <a href={`/users/${item.actor_username}/`}> {item.actor_username} </a> ), inviterProfileLink: ( - <a href={`/users/${item.username}`}> + <a href={`/users/${item.username}/`}> {item.username} </a> ) @@ -127,12 +127,12 @@ const getComponentForItem = item => { id="studio.activityRemoveCurator" values={{ removedProfileLink: ( - <a href={`/users/${item.username}`}> + <a href={`/users/${item.username}/`}> {item.username} </a> ), removerProfileLink: ( - <a href={`/users/${item.actor_username}`}> + <a href={`/users/${item.actor_username}/`}> {item.actor_username} </a> ) @@ -153,12 +153,12 @@ const getComponentForItem = item => { id="studio.activityBecomeOwner" values={{ promotedProfileLink: ( - <a href={`/users/${item.recipient_username}`}> + <a href={`/users/${item.recipient_username}/`}> {item.recipient_username} </a> ), promotorProfileLink: ( - <a href={`/users/${item.actor_username}`}> + <a href={`/users/${item.actor_username}/`}> {item.actor_username} </a> ) @@ -180,7 +180,7 @@ const getComponentForItem = item => { id="studio.activityBecomeHostAdminActor" values={{ newHostProfileLink: ( - <a href={`/users/${item.recipient_username}`}> + <a href={`/users/${item.recipient_username}/`}> {item.recipient_username} </a> ) @@ -190,12 +190,12 @@ const getComponentForItem = item => { id="studio.activityBecomeHost" values={{ newHostProfileLink: ( - <a href={`/users/${item.recipient_username}`}> + <a href={`/users/${item.recipient_username}/`}> {item.recipient_username} </a> ), actorProfileLink: ( - <a href={`/users/${item.actor_username}`}> + <a href={`/users/${item.actor_username}/`}> {item.actor_username} </a> ) diff --git a/src/views/studio/studio-member-tile.jsx b/src/views/studio/studio-member-tile.jsx index 13c94a3e4..5a546d996 100644 --- a/src/views/studio/studio-member-tile.jsx +++ b/src/views/studio/studio-member-tile.jsx @@ -37,7 +37,7 @@ const StudioMemberTile = ({ const [transferHostModalOpen, setTransferHostModalOpen] = useState(false); const [managerLimitReached, setManagerLimitReached] = useState(false); const {errorAlert, successAlert} = useAlertContext(); - const userUrl = `/users/${username}`; + const userUrl = `/users/${username}/`; return ( <div className="studio-member-tile"> <a href={userUrl}> diff --git a/src/views/studio/studio-project-tile.jsx b/src/views/studio/studio-project-tile.jsx index 788f028db..7f8aab1e7 100644 --- a/src/views/studio/studio-project-tile.jsx +++ b/src/views/studio/studio-project-tile.jsx @@ -18,7 +18,7 @@ const StudioProjectTile = ({ }) => { const [submitting, setSubmitting] = useState(false); const projectUrl = `/projects/${id}`; - const userUrl = `/users/${username}`; + const userUrl = `/users/${username}/`; const {errorAlert} = useContext(AlertContext); return ( <div className="studio-project-tile">