feat(front): render Instagram URLs as @handles in link fields (#21642)

LinkedIn and X links already show a readable handle in Twenty's link
fields. Instagram doesn't — it just shows `instagram.com`, which isn't
much help when you're scanning a record.

This adds the same handling for Instagram. `instagram.com/ptcrash` now
shows as `@ptcrash`, in tables, on record pages, and in the edit menu.
Post and reel links (`/p/...`, `/reel/...`) have no handle, so they fall
back to `Instagram`.

How it works:
- `Instagram` added to the `LinkType` enum
- `checkUrlType` detects `instagram.com`
- `getDisplayValueByUrlType` pulls the handle and prefixes `@`
- a shared `isSocialLinkType` helper keeps the three display components
in sync

Tested with unit tests for both helpers, the updated story, and manually
against a record whose Instagram field is
`http://instagram.com/ptcrash`.

Closes #21644

Co-authored-by: Johnny Martin <ptcrash@users.noreply.github.com>
This commit is contained in:
Johnny Martin
2026-06-23 11:25:50 -04:00
committed by GitHub
parent de610bc4e7
commit d4e4e2612b
11 changed files with 192 additions and 17 deletions
@@ -23,8 +23,16 @@ describe('checkUrlType', () => {
);
});
it('should detect Instagram urls', () => {
expect(checkUrlType('https://www.instagram.com/ptcrash')).toBe(
LinkType.Instagram,
);
expect(checkUrlType('instagram.com/ptcrash')).toBe(LinkType.Instagram);
});
it('should fall back to a generic url type', () => {
expect(checkUrlType('https://example.com')).toBe(LinkType.Url);
expect(checkUrlType('not-a-url')).toBe(LinkType.Url);
expect(checkUrlType('https://instagram.com')).toBe(LinkType.Url);
});
});
@@ -0,0 +1,15 @@
import { isSocialLinkType } from '~/utils/isSocialLinkType';
import { LinkType } from 'twenty-ui/navigation';
describe('isSocialLinkType', () => {
it('should return true for social link types', () => {
expect(isSocialLinkType(LinkType.LinkedIn)).toBe(true);
expect(isSocialLinkType(LinkType.Twitter)).toBe(true);
expect(isSocialLinkType(LinkType.Facebook)).toBe(true);
expect(isSocialLinkType(LinkType.Instagram)).toBe(true);
});
it('should return false for a generic url type', () => {
expect(isSocialLinkType(LinkType.Url)).toBe(false);
});
});
@@ -12,6 +12,9 @@ export const checkUrlType = (url: string) => {
if (/^(https?:\/\/)?(www\.)?facebook\.com\/.+$/.test(url)) {
return LinkType.Facebook;
}
if (/^(https?:\/\/)?(www\.)?instagram\.com\/.+$/.test(url)) {
return LinkType.Instagram;
}
return LinkType.Url;
};
@@ -0,0 +1,12 @@
import { LinkType } from 'twenty-ui/navigation';
// Link types rendered as a social handle (via SocialLink) instead of a plain RoundedLink
const SOCIAL_LINK_TYPES = [
LinkType.LinkedIn,
LinkType.Twitter,
LinkType.Facebook,
LinkType.Instagram,
];
export const isSocialLinkType = (type: LinkType): boolean =>
SOCIAL_LINK_TYPES.includes(type);