Skip to content
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

feat: Make getQueryParams more resilient #1778

Merged
merged 1 commit into from
Mar 4, 2025

Conversation

rafaeelaudibert
Copy link
Member

An SDK user has a slightly broken URL where they have two leading question marks, which is causing our queryParam parsing to break. Right now, because we split on ? and get the second split, we're simply getting an empty string.

We're fixing this in two ways:

  • where possible use built-in browser features to parse query params (with fallback to IE11 and op_mini)
  • trim leading question marks to avoid this from happening again

See https://posthoghelp.zendesk.com/agent/tickets/25469

@rafaeelaudibert rafaeelaudibert requested review from robbie-c and a team March 3, 2025 17:54
Copy link

vercel bot commented Mar 3, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
posthog-js ✅ Ready (Inspect) Visit Preview Mar 4, 2025 2:00pm

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

Enhanced URL query parameter parsing in request-utils.ts to handle malformed URLs and improve browser compatibility.

  • Added modern implementation using URL and URLSearchParams APIs for better query parameter handling
  • Created fallback implementation for older browsers (IE11, op_mini) that trims leading question marks
  • Split getQueryParams function into two parts for cleaner separation of modern and legacy code
  • Added handling for malformed URLs with multiple leading question marks
  • Improved error resilience for edge cases in URL parsing

1 file(s) reviewed, 2 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines 44 to 75
export const getQueryParam = function (url: string, param: string): string {
// Check if URL and URLSearchParams are available in the global scope
// Fall back to manual parsing if URL/URLSearchParams aren't supported
if (typeof URL === 'undefined' || typeof URLSearchParams === 'undefined') {
return getQueryParamFallback(url, param)
}

// Disabling compat/compat here because we've checked its existence above
const urlObj = new URL(url) // eslint-disable-line compat/compat

// Remove leading ? from search string if present
// This is not really necessary if there's a single ? in the search string
// but it's helpful if someone has some malformed URL with multiple ?s
const search = urlObj.search.replace(/^\?*/g, '')
const searchParams = new URLSearchParams(search) // eslint-disable-line compat/compat

return searchParams.get(param) ?? ''
}
Copy link
Member Author

@rafaeelaudibert rafaeelaudibert Mar 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open to feedback on whether this is needed. I think using the builtins are better than rolling our own code like we have on the fallback, but happy to be told otherwise and just stick to the previous thing we had going

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather only have 1 version. Bundle size is important. Sorry man =/ I'd love to kill off the old version and only have one that uses built-in methods, but if we need to support older browsers then we can't do that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a problem, will revert

Copy link

github-actions bot commented Mar 3, 2025

Size Change: +275 B (+0.01%)

Total Size: 3.56 MB

Filename Size Change
dist/array.full.es5.js 273 kB +25 B (+0.01%)
dist/array.full.js 376 kB +25 B (+0.01%)
dist/array.full.no-external.js 374 kB +25 B (+0.01%)
dist/array.js 184 kB +25 B (+0.01%)
dist/array.no-external.js 183 kB +25 B (+0.01%)
dist/customizations.full.js 14 kB +25 B (+0.18%)
dist/main.js 185 kB +25 B (+0.01%)
dist/module.full.js 376 kB +25 B (+0.01%)
dist/module.full.no-external.js 375 kB +25 B (+0.01%)
dist/module.js 184 kB +25 B (+0.01%)
dist/module.no-external.js 183 kB +25 B (+0.01%)
ℹ️ View Unchanged
Filename Size
dist/all-external-dependencies.js 219 kB
dist/dead-clicks-autocapture.js 14.5 kB
dist/exception-autocapture.js 9.51 kB
dist/external-scripts-loader.js 2.64 kB
dist/posthog-recorder.js 212 kB
dist/recorder-v2.js 115 kB
dist/recorder.js 115 kB
dist/surveys-preview.js 71.3 kB
dist/surveys.js 76 kB
dist/tracing-headers.js 1.76 kB
dist/web-vitals.js 10.4 kB

compressed-size-action

@rafaeelaudibert rafaeelaudibert force-pushed the make-getQueryParams-more-resilient branch 2 times, most recently from 47fe115 to 8c0bb38 Compare March 3, 2025 18:06
@rafaeelaudibert rafaeelaudibert added the bump patch Bump patch version when this PR gets merged label Mar 3, 2025
// Check if URL and URLSearchParams are available in the global scope
// Fall back to manual parsing if URL/URLSearchParams aren't supported
if (typeof URL === 'undefined' || typeof URLSearchParams === 'undefined') {
return getQueryParamFallback(url, param)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any downside to just always calling that function? It's nicer to use the built-in parsing, and if we could guarantee that it was available, we'd just use that, but given we have to have a fallback anyway, why add extra bytes to the bundle with two implementations?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because I'd prefer to use the built-in if it exists, but I'm fine with keeping the old-but-proven-to-work function instead, and just fix it (which I did anyway)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which is basically what I commented here: #1778 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you prefer we kept that old code instead and never add the new one?

@rafaeelaudibert rafaeelaudibert requested a review from robbie-c March 3, 2025 19:26
An SDK user has a slightly broken URL where they have two leading question marks, which is causing our `queryParam` parsing to break. Right now, because we split on `?` and get the second split, we're simply getting an empty string.

Even though this is liekly user error, we're fixing this by trimming leading question marks to avoid this from happening again

See https://posthoghelp.zendesk.com/agent/tickets/25469
@rafaeelaudibert rafaeelaudibert force-pushed the make-getQueryParams-more-resilient branch from 8c0bb38 to 3e9745e Compare March 4, 2025 13:57
@rafaeelaudibert
Copy link
Member Author

@robbie-c Ready for a re-review, I've removed the new code and simply adapted the old one

@robbie-c robbie-c merged commit be9d7dd into main Mar 4, 2025
25 checks passed
@robbie-c robbie-c deleted the make-getQueryParams-more-resilient branch March 4, 2025 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bump patch Bump patch version when this PR gets merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants