-
Notifications
You must be signed in to change notification settings - Fork 2.8k
LinkedIn field update #2852
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
LinkedIn field update #2852
Conversation
Removed the /in/ as we'll need to verfiy company and individual pages shortly. The /in/ is just for individuals.
|
@marcusljf is attempting to deploy a commit to the Dub Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughUpdated the LinkedIn input label in the OnlinePresenceForm from "linkedin.com/in" to "linkedin.com", and extended LinkedIn handle parsing in social-utils to accept both personal ( Changes
Sequence Diagram(s)(omitted — changes are presentational and regex-only, not control-flow.) Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/web/lib/social-utils.ts (1)
92-95: Also strip URL fragments (#...).Minor hygiene to avoid keeping anchors like “#experience”.
Apply this diff:
handle = handle .replace(/\/.*$/, "") .replace(/\?.*$/, "") + .replace(/#.*$/, "") .replace(allowedChars, "");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/web/lib/social-utils.ts(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Vade Review
🔇 Additional comments (1)
apps/web/lib/social-utils.ts (1)
31-35: Ensure LinkedIn link builders preserve or infer company vs individual typeFound only sanitizeSocialHandle(input, "linkedin") at apps/web/lib/actions/partners/update-online-presence.ts:39; search for 'linkedin.com/(in|company)' returned no matches. If only the slug is stored, downstream link construction must either persist the type, infer it, or attempt both '/in/' and '/company/' when generating URLs.
| }, | ||
| linkedin: { | ||
| patterns: [/^(?:.*\.)?linkedin\.com\/(?:in\/)?([^\/\?]+)/i], | ||
| patterns: [/^(?:.*\.)?linkedin\.com\/(?:in\/|company\/)?([^\/\?]+)/i], |
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.
Handle path-only inputs and avoid false positives.
With the UI prefix now “linkedin.com”, users may enter “in/”, “company/”, or a bare slug. The current regex only matches when the host is present and can also accept unrelated sections (e.g., “groups”). Tighten and expand patterns to: (a) require in|company when a host is present; (b) support path-only inputs; (c) optionally allow bare slugs.
Apply this diff:
- patterns: [/^(?:.*\.)?linkedin\.com\/(?:in\/|company\/)?([^\/\?]+)/i],
+ patterns: [
+ /^(?:.*\.)?linkedin\.com\/(?:in|company)\/([^\/\?#]+)/i,
+ /^(?:in|company)\/([^\/\?#]+)/i,
+ /^([^\/\?#]+)$/i,
+ ],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| patterns: [/^(?:.*\.)?linkedin\.com\/(?:in\/|company\/)?([^\/\?]+)/i], | |
| patterns: [ | |
| /^(?:.*\.)?linkedin\.com\/(?:in|company)\/([^\/\?#]+)/i, | |
| /^(?:in|company)\/([^\/\?#]+)/i, | |
| /^([^\/\?#]+)$/i, | |
| ], |
🤖 Prompt for AI Agents
In apps/web/lib/social-utils.ts around line 32, the LinkedIn pattern should be
tightened and expanded: replace the current host-optional regex with a set of
alternatives that (1) when a host is present requires the path to start with in/
or company/, (2) supports path-only inputs like "in/slug" or "company/slug" (no
host), and (3) also optionally accepts a bare slug; implement this by using a
single combined regex that matches either: full URLs with an optional subdomain
but mandates the path prefix (in|company), OR path-only entries that start with
(in|company)/, OR bare slugs (alphanumeric/dashes/underscores) as a fallback,
and ensure the capture group extracts only the slug portion.
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.
Additional Comments:
apps/web/ui/partners/online-presence-summary.tsx (lines 66-66):
LinkedIn company pages will generate broken links because the summary component hardcodes /in/ path for all LinkedIn profiles, but the form now accepts both individual profiles (/in/) and company pages (/company/).
View Details
📝 Patch Details
diff --git a/apps/web/lib/social-utils.ts b/apps/web/lib/social-utils.ts
index 7abf34bab..b2a7aa188 100644
--- a/apps/web/lib/social-utils.ts
+++ b/apps/web/lib/social-utils.ts
@@ -29,7 +29,10 @@ const PLATFORM_CONFIGS: Record<SocialPlatform, SocialPlatformConfig> = {
maxLength: 15,
},
linkedin: {
- patterns: [/^(?:.*\.)?linkedin\.com\/(?:in\/|company\/)?([^\/\?]+)/i],
+ patterns: [
+ /^(?:.*\.)?linkedin\.com\/(in\/|company\/)([^\/\?]+)/i,
+ /^(?:.*\.)?linkedin\.com\/([^\/\?]+)/i // fallback for URLs without explicit type
+ ],
allowedChars: /[^\w-]/g,
maxLength: 30,
},
@@ -84,15 +87,38 @@ export const sanitizeSocialHandle = (
const match = handle.match(pattern);
if (match) {
- handle = match[1];
+ if (platform === "linkedin" && match[1] && match[2]) {
+ // For LinkedIn, preserve the URL type (in/ or company/) as a prefix
+ const urlType = match[1]; // "in/" or "company/"
+ const actualHandle = match[2];
+ handle = `${urlType}${actualHandle}`;
+ } else {
+ // For other platforms or LinkedIn URLs without explicit type, use the handle as-is
+ handle = match[1] || match[2] || match[0];
+ }
break;
}
}
- handle = handle
- .replace(/\/.*$/, "")
- .replace(/\?.*$/, "")
- .replace(allowedChars, "");
+ // Clean up the handle, but preserve LinkedIn prefixes
+ if (platform === "linkedin" && (handle.startsWith('in/') || handle.startsWith('company/'))) {
+ // For prefixed LinkedIn handles, only clean the handle part
+ const parts = handle.split('/');
+ if (parts.length === 2) {
+ const prefix = parts[0] + '/';
+ let cleanHandle = parts[1]
+ .replace(/\/.*$/, "")
+ .replace(/\?.*$/, "")
+ .replace(allowedChars, "");
+ handle = prefix + cleanHandle;
+ }
+ } else {
+ // Regular cleanup for other platforms
+ handle = handle
+ .replace(/\/.*$/, "")
+ .replace(/\?.*$/, "")
+ .replace(allowedChars, "");
+ }
if (maxLength) {
handle = handle.substring(0, maxLength);
diff --git a/apps/web/ui/partners/online-presence-form.tsx b/apps/web/ui/partners/online-presence-form.tsx
index e04778ae6..c1d4d30b4 100644
--- a/apps/web/ui/partners/online-presence-form.tsx
+++ b/apps/web/ui/partners/online-presence-form.tsx
@@ -70,12 +70,25 @@ interface OnlinePresenceFormProps {
export function useOnlinePresenceForm({
partner,
}: Pick<OnlinePresenceFormProps, "partner">) {
+ // Extract clean LinkedIn handle for display
+ const getCleanLinkedInHandle = (linkedinValue?: string | null) => {
+ if (!linkedinValue) return undefined;
+
+ // Remove prefixes for display in form
+ if (linkedinValue.startsWith('company/')) {
+ return linkedinValue.substring(8);
+ } else if (linkedinValue.startsWith('in/')) {
+ return linkedinValue.substring(3);
+ }
+ return linkedinValue;
+ };
+
return useForm<OnlinePresenceFormData>({
defaultValues: {
website: partner?.website ? getPrettyUrl(partner.website) : undefined,
youtube: partner?.youtube || undefined,
twitter: partner?.twitter || undefined,
- linkedin: partner?.linkedin || undefined,
+ linkedin: getCleanLinkedInHandle(partner?.linkedin),
instagram: partner?.instagram || undefined,
tiktok: partner?.tiktok || undefined,
},
@@ -294,7 +307,7 @@ export const OnlinePresenceForm = forwardRef<
<FormRow
label="LinkedIn"
property="linkedin"
- prefix="in/"
+ prefix={""}
verifiedAtField="linkedinVerifiedAt"
icon={LinkedIn}
onVerifyClick={() =>
diff --git a/apps/web/ui/partners/online-presence-summary.tsx b/apps/web/ui/partners/online-presence-summary.tsx
index 497c64807..0f1ecb9b3 100644
--- a/apps/web/ui/partners/online-presence-summary.tsx
+++ b/apps/web/ui/partners/online-presence-summary.tsx
@@ -60,11 +60,40 @@ const fields: {
{
label: "LinkedIn",
icon: LinkedIn,
- data: (partner) => ({
- value: partner.linkedin,
- verified: !!partner.linkedinVerifiedAt,
- href: `https://linkedin.com/in/${partner.linkedin}`,
- }),
+ data: (partner) => {
+ if (!partner.linkedin) {
+ return {
+ value: null,
+ verified: false,
+ href: null,
+ };
+ }
+
+ // Handle prefixed LinkedIn handles that preserve URL type
+ const isCompanyPage = partner.linkedin.startsWith('company/');
+ const isIndividualProfile = partner.linkedin.startsWith('in/');
+
+ let href: string;
+ let displayValue: string;
+
+ if (isCompanyPage) {
+ href = `https://linkedin.com/${partner.linkedin}`;
+ displayValue = partner.linkedin.substring(8); // Remove 'company/' prefix
+ } else if (isIndividualProfile) {
+ href = `https://linkedin.com/${partner.linkedin}`;
+ displayValue = partner.linkedin.substring(3); // Remove 'in/' prefix
+ } else {
+ // Legacy data without prefix - assume individual profile
+ href = `https://linkedin.com/in/${partner.linkedin}`;
+ displayValue = partner.linkedin;
+ }
+
+ return {
+ value: displayValue,
+ verified: !!partner.linkedinVerifiedAt,
+ href,
+ };
+ },
},
{
label: "Instagram",
Analysis
LinkedIn company pages generate broken links due to hardcoded /in/ path in summary component
What fails: OnlinePresenceSummary component in apps/web/ui/partners/online-presence-summary.tsx hardcodes /in/ path for all LinkedIn profiles (line 66), but form accepts both individual profiles (/in/) and company pages (/company/)
How to reproduce:
# 1. Enter company LinkedIn URL in form: https://linkedin.com/company/acme-corp
# 2. Form sanitizes to handle: "acme-corp" (losing URL type information)
# 3. Summary reconstructs as: https://linkedin.com/in/acme-corp (incorrect)
# 4. Click link - leads to 404 because company pages use /company/ not /in/Result: All LinkedIn company page links are broken, generating 404s when clicked
Expected: Company URLs should reconstruct as https://linkedin.com/company/acme-corp per LinkedIn's official company page URL format
Root cause: sanitizeSocialHandle() in social-utils.ts strips URL type information, and summary component assumes all LinkedIn URLs are individual profiles
Removed the /in/ as we'll need to verfiy both company and individual pages shortly. The /in/ is just for individuals.
Summary by CodeRabbit
Style
Bug Fixes