Skip to content

Conversation

@kishandev2509
Copy link
Contributor

@kishandev2509 kishandev2509 commented Jan 7, 2026

Pull Request: Add JioHotstar Deep Link Support

🎯 Summary

Adds jiohotstarHandler to convert JioHotstar web URLs to native app deep links, following the established Spotify/Netflix pattern.

📋 Changes

New Handler: jiohotstarHandler

// Matches: https://www.hotstar.com/in/shows/1260019000
// Generates: 
//   iOS: hotstar://content/1260019000
//   Android: intent://1260019000#Intent;scheme=hotstar;package=in.startv.hotstar;...

Supported patterns:

✅ https://www.hotstar.com/in/shows/1260019000
✅ https://hotstar.com/movies/1270600012
✅ https://jiohotstar.com/play/abc123xyz  
✅ https://www.hotstar.com/live/cricket-match-456

Closes #69

Summary by CodeRabbit

  • New Features

    • Added Jio Hotstar deep linking support for iOS and Android.
  • Improvements

    • Simplified Twitch Android deep link behavior (removed browser fallback parameter).
  • Documentation

    • Added Jio Hotstar deep link examples and moved the "Unknown URL" section.
    • Updated demo app with a Jio Hotstar example link.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

📝 Walkthrough

Walkthrough

Adds Jio Hotstar deep-link support via a new jioHotstarHandler, adds a shared URL utility, exports a central handlers array used by core, updates the Twitch handler URI, and adds a Hotstar example link and README examples.

Changes

Cohort / File(s) Summary
Jio Hotstar handler & types
packages/core/src/platforms/jioHotstar.ts, packages/core/src/types.ts
New jioHotstarHandler implemented; matches Hotstar/JioHotstar/Startv domains and /shows, /movies, /play patterns, extracts content/video IDs, builds hotstar:// iOS links and Android intent URIs. Adds 'jiohotstar' to Platform union.
Platforms registry & core wiring
packages/core/src/platforms/index.ts, packages/core/src/index.ts
Introduces export const handlers: DeepLinkHandler[] and reorders/expands platform exports. generateDeepLink now iterates the imported handlers array instead of a locally assembled list.
Shared utility & Twitch handler
packages/core/src/utils.ts, packages/core/src/platforms/twitch.ts
Adds getUrlWithoutProtocol utility and uses it in the Twitch handler; Twitch Android intent URI simplified by removing the browser_fallback_url parameter.
Docs & demo
packages/core/README.md, apps/demo/index.html
README gains a "Jio Hotstar" section with examples; demo index.html adds a Jio Hotstar example link in the UI.

Sequence Diagram(s)

(Skipped — changes add a handler and a registry export; control flow remains straightforward.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • mdsaban

Poem

🐰📺 I sniffed a Hotstar link beneath the moon,
I pulled its IDs and hummed a happy tune,
iOS hops open, Android hops too,
A tiny rabbit hop — the app now finds you! 🥕✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive Changes to twitch.ts (removing browser_fallback_url) and the refactoring of handler imports in index.ts are tangentially related but appear to support the handler pattern standardization. However, the Twitch modification seems partially out of scope. Clarify whether the Twitch Android deep link modification and handler registry refactoring are necessary for Jio Hotstar support or represent separate improvements.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the primary change: adding deep link support for Jio Hotstar with new types, utilities, and demo examples, which aligns with all the file modifications.
Linked Issues check ✅ Passed All requirements from issue #69 are met: jioHotstarHandler implemented with pattern matching for multiple domains, content ID extraction, deep link generation for iOS/Android, handler registry integration, and demo examples added.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @apps/demo/index.html:
- Around line 104-112: The icon filename in the Jio Hotstar link is camelCase;
update the img src in the anchor with class "jio-hotstar-link" (the <span
class="link-icon"> image) to use the lowercase filename '/icons/jiohotstar.svg'
instead of '/icons/jioHotstar.svg' so it matches the other platform icon
filenames.

In @packages/core/README.md:
- Around line 195-201: Documentation and implementation diverge: the jioHotstar
handler (used by generateDeepLink) emits iOS links as
hotstar://content/${contentId} while README shows hotstar://${contentId}; either
update the README example to include the "content/" segment or change the
jioHotstar handler to build hotstar://${contentId} instead (modify the code path
inside the jioHotstar handler used by generateDeepLink), and add unit tests for
the jioHotstar handler/generateDeepLink to assert both iOS and Android outputs
match the chosen canonical format.

In @packages/core/src/platforms/jioHotstar.ts:
- Around line 5-8: The complex inline regex used in the match function should be
extracted to a named constant (e.g., JIO_HOTSTAR_URL_REGEX) and documented:
create a top-level constant string or RegExp with an end anchor ($), add a
comment block that explains the full URL structure, shows example URLs for each
variant (with and without the optional middle segment), and explicitly states
which capture group corresponds to contentId (group 1) vs videoId (group 2) and
when group 2 is present (e.g., nested episode/video paths like
/show/.../season/.../episodeId or /movie/.../watch/videoId). Replace the inline
literal in match with getUrlWithoutProtocol(url).match(JIO_HOTSTAR_URL_REGEX)
and ensure the regex includes the final $ to avoid matching extra trailing
segments.

In @packages/core/src/types.ts:
- Line 16: Change the platform literal 'jioHotstar' to lowercase 'jiohotstar' in
the union type declaration in types.ts and update every related reference: the
handler implementation that checks or returns this platform value, any platform
detection/comparison logic, the demo HTML class/icon names, and documentation
examples so they all use 'jiohotstar' consistently.
🧹 Nitpick comments (1)
packages/core/src/utils.ts (1)

36-37: Add input validation and documentation to the utility function.

The getUrlWithoutProtocol function is now shared across multiple platform handlers (twitch, jioHotstar) but lacks input validation and documentation:

  1. Missing input validation: The function doesn't handle null, undefined, or empty string inputs, which could cause runtime errors in consuming handlers.

  2. No documentation: Add JSDoc comments explaining:

    • The function's purpose
    • Expected input format
    • Return value format
    • Example usage
  3. Edge case consideration: While the current implementation handles typical HTTP/HTTPS URLs well, consider whether edge cases (e.g., URLs with unusual subdomains like "www.www.example.com") need explicit handling or documentation.

🛡️ Proposed improvements
+/**
+ * Strips the protocol (http/https) and leading 'www.' from a URL string.
+ * 
+ * @param url - The URL string to process (e.g., "https://www.example.com")
+ * @returns The URL without protocol and www prefix (e.g., "example.com")
+ * 
+ * @example
+ * getUrlWithoutProtocol("https://www.example.com") // returns "example.com"
+ * getUrlWithoutProtocol("http://example.com") // returns "example.com"
+ */
-export const getUrlWithoutProtocol = (url: string) =>
-  url.replace(/^https?:\/\//, '').replace(/^www\./, '');
+export const getUrlWithoutProtocol = (url: string): string => {
+  if (!url || typeof url !== 'string') {
+    return '';
+  }
+  return url.replace(/^https?:\/\//, '').replace(/^www\./, '');
+};
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between feb26ee and 0fa2d74.

⛔ Files ignored due to path filters (1)
  • apps/demo/public/icons/jioHotstar.svg is excluded by !**/*.svg
📒 Files selected for processing (8)
  • apps/demo/index.html
  • packages/core/README.md
  • packages/core/src/index.ts
  • packages/core/src/platforms/index.ts
  • packages/core/src/platforms/jioHotstar.ts
  • packages/core/src/platforms/twitch.ts
  • packages/core/src/types.ts
  • packages/core/src/utils.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-02T21:27:30.363Z
Learnt from: tanmoyPaul12
Repo: mdsaban/universal-app-opener PR: 0
File: :0-0
Timestamp: 2026-01-02T21:27:30.363Z
Learning: In the mdsaban/universal-app-opener repository, the Platform type in packages/core/src/types.ts already includes 'github' and 'twitch' platforms in the main branch.

Applied to files:

  • packages/core/src/platforms/twitch.ts
  • packages/core/src/types.ts
  • packages/core/src/index.ts
  • packages/core/src/platforms/index.ts
🧬 Code graph analysis (2)
packages/core/src/platforms/jioHotstar.ts (3)
packages/core/src/platforms/index.ts (1)
  • jioHotstarHandler (24-24)
packages/core/src/types.ts (1)
  • DeepLinkHandler (31-48)
packages/core/src/utils.ts (1)
  • getUrlWithoutProtocol (36-37)
packages/core/src/platforms/index.ts (2)
packages/core/src/types.ts (1)
  • DeepLinkHandler (31-48)
packages/core/src/platforms/jioHotstar.ts (1)
  • jioHotstarHandler (4-30)
🔇 Additional comments (8)
packages/core/README.md (2)

186-193: Twitch Android deep link update aligns with code changes.

The removal of browser_fallback_url from the Twitch Android intent example correctly reflects the refactored implementation in packages/core/src/platforms/twitch.ts.


203-210: Good addition of the Unknown URL section.

Documenting the behavior for unrecognized URLs helps set clear expectations for library users.

packages/core/src/platforms/twitch.ts (2)

2-2: Good refactoring to use shared utility.

Moving the URL protocol/www stripping logic to a shared utility function (getUrlWithoutProtocol) eliminates code duplication and improves maintainability.


50-50: Ensure timeout-based fallback is acceptable for Android users without the Twitch app.

The Android intent URL lacks the browser_fallback_url parameter, unlike other platforms (LinkedIn, Pinterest, Snapchat). Fallback handling is delegated to openLink() in packages/core/src/index.ts, which implements a JavaScript timeout-based approach: if the deep link doesn't open the app within 2500ms (default), it falls back to the web URL.

This differs from OS-level immediate fallback (browser_fallback_url). Verify that the 2500ms delay is acceptable for the user experience when the Twitch app is not installed, and consider whether platform consistency (using browser_fallback_url like other apps) would be preferable.

packages/core/src/index.ts (1)

1-1: LGTM! Clean refactoring to centralize handler management.

The change to import the handlers array from ./platforms instead of constructing it locally improves maintainability and follows good separation of concerns.

Also applies to: 10-10

packages/core/src/platforms/jioHotstar.ts (2)

1-2: LGTM! Imports are correct.

The necessary types and utilities are properly imported and used throughout the handler.


10-29: The hotstar:// URI scheme could not be verified in public documentation and may need validation.

  1. The iOS deep link scheme hotstar://content/{id} has no public documentation. Sources indicate Hotstar primarily uses App Links (HTTPS URLs) for deep linking. Recommend verifying this scheme works by testing with the native app or checking Hotstar's official technical documentation.

  2. The Android package name in.startv.hotstar and intent format are correct.

  3. The contentId/videoId behavior is sound—the regex makes videoId (match[2]) optional while contentId (match[1]) is always captured; the code correctly prioritizes videoId when present.

  4. Input validation: The regex character class [a-zA-Z0-9_-]+ prevents empty strings, so additional validation for captured IDs is not critical.

packages/core/src/platforms/index.ts (1)

1-1: LGTM! Handler registration follows the established pattern.

The changes correctly:

  • Import and export the new jioHotstarHandler
  • Include it in the handlers array at the appropriate alphabetical position
  • Maintain separation between the handlers array and unknownHandler (which serves as the fallback)

The implementation is consistent with the existing platform handler architecture.

Also applies to: 6-6, 19-36, 38-54

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/core/src/platforms/jioHotstar.ts (2)

24-30: Consider prefixing unused variable with underscore.

The type variable is destructured from the PATTERNS tuple but never used. If it's intentionally unused, prefix it with an underscore to indicate this: [_type, pattern].

♻️ Proposed refactor
-    for (const [type, pattern] of PATTERNS) {
+    for (const [_type, pattern] of PATTERNS) {
       const match = urlWithoutProtocol.match(pattern);
       if (match) return match;
     }

35-54: Consider refactoring to reduce code duplication.

Both the videoId and contentId branches construct nearly identical deep link objects. Extract the ID selection logic to reduce duplication and improve maintainability.

♻️ Proposed refactor
  build: (webUrl, match) => {
    const contentId = match[1];
    const videoId = match[2];
+   const id = videoId || contentId;

-   if (videoId) {
-     return {
-       webUrl,
-       ios: `hotstar://content/${videoId}`,
-       android: `intent://${videoId}#Intent;scheme=hotstar;package=in.startv.hotstar;end`,
-       platform: 'jiohotstar',
-     };
-   }
-
    return {
      webUrl,
-     ios: `hotstar://content/${contentId}`,
-     android: `intent://${contentId}#Intent;scheme=hotstar;package=in.startv.hotstar;end`,
+     ios: `hotstar://content/${id}`,
+     android: `intent://${id}#Intent;scheme=hotstar;package=in.startv.hotstar;end`,
      platform: 'jiohotstar',
    };
  },
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f9ae35 and 0d8fc87.

📒 Files selected for processing (1)
  • packages/core/src/platforms/jioHotstar.ts
🧰 Additional context used
🧬 Code graph analysis (1)
packages/core/src/platforms/jioHotstar.ts (3)
packages/core/src/platforms/index.ts (1)
  • jioHotstarHandler (26-26)
packages/core/src/types.ts (1)
  • DeepLinkHandler (33-50)
packages/core/src/utils.ts (1)
  • getUrlWithoutProtocol (36-37)
🔇 Additional comments (2)
packages/core/src/platforms/jioHotstar.ts (2)

1-2: LGTM!

The imports are appropriate and used correctly throughout the file.


4-21: LGTM!

The pattern definitions are well-documented and correctly match the intended URL structures. The extraction of patterns to a named constant and the addition of comprehensive comments address the previous review feedback effectively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Jio Hotstar Deeplink Support

1 participant