Skip to content

docs: improve structure and support multi-langs#47

Merged
hyochan merged 4 commits into
mainfrom
docs/lifecycle-subs-improve-details
Nov 26, 2025
Merged

docs: improve structure and support multi-langs#47
hyochan merged 4 commits into
mainfrom
docs/lifecycle-subs-improve-details

Conversation

@hyochan
Copy link
Copy Markdown
Member

@hyochan hyochan commented Nov 26, 2025

Summary by CodeRabbit

  • New Features

    • Added Dart language support for code examples
    • Introduced multi-language code samples (TypeScript, Swift, Kotlin, Dart) across documentation
    • Added URL hash-based tab initialization for platform-specific content
    • New alert card component for improved documentation styling
  • Documentation

    • Reorganized documentation structure with dedicated feature guides
    • Added comprehensive guides for purchases, subscriptions, and offer code redemption
    • Expanded external purchase documentation with multi-language examples
    • New subscription lifecycle documentation
  • Style

    • Changed page scrolling behavior from smooth to instant
    • Improved dark mode support for UI components
    • Enhanced documentation visual hierarchy with new card-based layouts

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

@hyochan hyochan added the 📖 documentation Improvements or additions to documentation label Nov 26, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 26, 2025

Walkthrough

Documentation infrastructure expanded with multi-language support through new LanguageTabs component; Dart language added to CodeBlock; documentation reorganized into features/* and updates/* hierarchies; scroll behavior changed from smooth to instant across components; new comprehensive docs pages created for subscription, purchase flow, and offer code redemption.

Changes

Cohort / File(s) Summary
UI Components – Scroll & Language Support
packages/docs/src/components/AnchorLink.tsx, packages/docs/src/components/CodeBlock.tsx, packages/docs/src/components/LanguageTabs.tsx, packages/docs/src/components/PlatformTabs.tsx
AnchorLink switches to instant scroll behavior; CodeBlock adds Dart language support with syntax highlighting and keyword handling; LanguageTabs component introduced for tabbed multi-language code samples; PlatformTabs adds hash-based active tab initialization
Hooks & Utilities
packages/docs/src/hooks/useScrollToHash.ts, packages/docs/src/components/SearchModal.tsx
useScrollToHash replaces smooth scrolling with instant behavior; SearchModal updates external-purchase path
Global Styles
packages/docs/src/styles/base.css, packages/docs/src/styles/components.css, packages/docs/src/styles/dark-mode.css
Removes global smooth scroll; adds Language Tabs and Alert Card component styles; extends info-note styling; adds dark-mode variants for alert cards
Navigation & Structure
packages/docs/src/pages/docs.tsx, packages/docs/src/pages/home.tsx, packages/docs/src/pages/tutorials.tsx
docs.tsx restructures routes under features/* and updates/* with new lifecycle/subscription path; home.tsx updates version link; tutorials.tsx integrates useScrollToHash and wraps headings with AnchorLink
Documentation Pages – Refactored
packages/docs/src/pages/docs/apis.tsx, packages/docs/src/pages/docs/errors.tsx, packages/docs/src/pages/docs/events.tsx, packages/docs/src/pages/docs/features/external-purchase.tsx, packages/docs/src/pages/docs/features/subscription-upgrade-downgrade.tsx
Replaces GraphQL code blocks and single-language snippets with LanguageTabs for multi-language (TypeScript, Swift, Kotlin, Dart) code samples; restructures content with alert-card components
Documentation Pages – New
packages/docs/src/pages/docs/features/purchase.tsx, packages/docs/src/pages/docs/features/subscription.tsx, packages/docs/src/pages/docs/features/offer-code-redemption.tsx, packages/docs/src/pages/docs/lifecycle/subscription.tsx
New comprehensive guides for purchase flow, subscription management, offer code redemption, and subscription lifecycle with multi-language code samples and platform-specific flows
Documentation Pages – Reorganized
packages/docs/src/pages/docs/features.tsx (deleted), packages/docs/src/pages/docs/lifecycle/index.tsx, packages/docs/src/pages/docs/updates/announcements.tsx, packages/docs/src/pages/docs/updates/notes.tsx, packages/docs/src/pages/docs/updates/versions.tsx
Features.tsx removed (content migrated); lifecycle and updates pages updated with corrected import paths and component renames

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Route restructuring complexity: docs.tsx introduces significant path reorganization (features/*, updates/*) requiring careful mapping validation
  • Multi-language component integration: LanguageTabs replaces numerous CodeBlock instances across multiple pages with consistent pattern; verify all language variants are present and correct
  • New documentation density: Four new comprehensive doc pages (purchase, subscription, offer-code-redemption, lifecycle/subscription) with embedded code samples across multiple languages
  • Scroll behavior impact: Verify instant scroll behavior works correctly across all anchor link contexts and doesn't break existing UX expectations
  • Interconnected changes: Route changes in docs.tsx must align with import paths and navigation links across updated pages

Possibly related PRs

Poem

🐇 Hop through the docs with languages bright,
TypeScript, Swift, Kotlin—now Dart takes flight!
Tabs stack the code in tabbed delight,
Instant scrolls replace the smooth tonight,
Routes reorganized, features in sight! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: documentation structure improvements and multi-language support additions throughout the docs site.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/lifecycle-subs-improve-details

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1492dee and 6c8edb1.

📒 Files selected for processing (3)
  • packages/docs/src/pages/docs.tsx (8 hunks)
  • packages/docs/src/pages/docs/features/offer-code-redemption.tsx (1 hunks)
  • packages/docs/src/pages/docs/features/subscription.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
packages/docs/src/pages/docs/features/subscription.tsx (2)
packages/gql/src/generated/types.ts (1)
  • Subscription (782-794)
packages/docs/src/hooks/useScrollToHash.ts (1)
  • useScrollToHash (4-28)
packages/docs/src/pages/docs/features/offer-code-redemption.tsx (1)
packages/docs/src/hooks/useScrollToHash.ts (1)
  • useScrollToHash (4-28)
packages/docs/src/pages/docs.tsx (1)
packages/docs/src/components/MenuDropdown.tsx (1)
  • MenuDropdown (16-128)
⏰ 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: Test Android
🔇 Additional comments (13)
packages/docs/src/pages/docs/features/offer-code-redemption.tsx (4)

1-10: Well-structured documentation page.

The component is well-organized with proper imports and uses the useScrollToHash hook consistently with other documentation pages. The structure follows established patterns in the codebase.


57-156: iOS implementation section looks comprehensive.

The iOS section provides excellent coverage with usage examples, complete examples including listener setup, and testing guidance. The code samples across TypeScript, Swift, Kotlin, and Dart are consistent in their approach.


374-377: Appropriate placeholder for iOS-only functionality.

The Swift placeholder correctly indicates that this is Android-only functionality. Users looking at the Swift tab will understand they should use the iOS-specific method instead.


438-455: Related links section provides good navigation.

The related links connect this page well to related documentation (API reference, Purchase Flow, Events & Listeners), helping users explore related topics.

packages/docs/src/pages/docs/features/subscription.tsx (5)

1-17: Comprehensive subscription documentation page.

Excellent introductory section that clearly outlines what the page covers and the different types of subscription offers.


42-77: Clear platform differences table with helpful tip.

The platform differences table concisely explains the key behavioral differences between iOS and Android. The info alert about fetching products first is a helpful reminder for developers.


1085-1171: Excellent subscription scenarios documentation.

The cancellation, restore, and refund scenarios are documented clearly with practical examples. The refund scenario warning is particularly valuable as it highlights a common pitfall where client-side checks can incorrectly grant access to refunded purchases.


1191-1211: Thorough Android limitation documentation.

The info alert clearly explains Android's limitations regarding client-side subscription status checking and provides concrete recommendations (Google Play Developer API, RTDN, server-side records) for proper subscription management.


1433-1456: All referenced documentation links are properly configured and files exist.

Verification confirms all three routes in the "See Also" section have corresponding documentation files:

  • /docs/features/subscription-upgrade-downgradepackages/docs/src/pages/docs/features/subscription-upgrade-downgrade.tsx
  • /docs/lifecycle/subscriptionpackages/docs/src/pages/docs/lifecycle/subscription.tsx
  • /tutorials#verify-purchasepackages/docs/src/pages/tutorials.tsx
packages/docs/src/pages/docs.tsx (4)

6-21: Clean import organization for new documentation pages.

The new imports are well-organized, grouping related pages together (lifecycle, features, updates). The naming convention is consistent with the routing structure.


80-87: MenuDropdown properly configured for Life Cycle section.

The MenuDropdown component is correctly set up with the title linking to the main lifecycle page and the Subscription subpage as a dropdown item. This follows the same pattern used for Android Setup.


143-190: Features section navigation is comprehensive.

The Features section now includes all the new documentation pages with consistent NavLink patterns. The paths follow a logical hierarchy under /docs/features/.


223-256: Routes properly match navigation structure.

All routes are correctly defined to match the sidebar navigation. The hierarchical structure (features/*, updates/*, lifecycle/*) is consistently applied.


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
Copy Markdown
Contributor

@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 (6)
packages/docs/src/styles/dark-mode.css (1)

149-166: Dark-mode alert variants are well integrated

The new .alert-card--info|warning|success rules fit the existing dark palette and keep text legible; if you add more variants later, consider factoring shared alert-card styles into a common class to avoid duplication.

packages/docs/src/components/PlatformTabs.tsx (1)

1-33: Hash‑driven tab selection is useful; consider guarding window for SSR/tests

The hash‑based default and hashchange listener give nice deep‑link behavior for iOS/Android sections. If this component is ever rendered in SSR or non‑DOM test environments, the window.location.hash usage in the useState initializer could throw—consider guarding with typeof window !== 'undefined' or moving initial hash inspection into useEffect with a safe default.

packages/docs/src/components/LanguageTabs.tsx (1)

21-45: Initialize activeTab from available languages, not hardcoded 'typescript'

Right now activeTab always starts as 'typescript', even if the caller only provides (say) Swift/Kotlin/Dart. That would render an empty content area until the user clicks a tab.

You can make the component more robust by deriving the initial tab from children:

-function LanguageTabs({ children }: LanguageTabsProps) {
-  const [activeTab, setActiveTab] = useState<Language>('typescript');
-
-  const availableLanguages = (Object.keys(children) as Language[]).filter(
-    (lang) => children[lang] !== undefined
-  );
+function LanguageTabs({ children }: LanguageTabsProps) {
+  const availableLanguages = (Object.keys(children) as Language[]).filter(
+    (lang) => children[lang] !== undefined
+  );
+
+  const [activeTab, setActiveTab] = useState<Language>(
+    availableLanguages[0] ?? 'typescript'
+  );

This keeps existing behavior when TS is present, but degrades gracefully for other combinations.

packages/docs/src/components/CodeBlock.tsx (1)

3-13: Align highlightCode language typing with CodeBlockProps.language

Dart support and the shared Swift/Kotlin/Dart highlighting branch look good and follow the existing escaping pattern. One small type-safety improvement: highlightCode currently takes language: string, so adding a new language to CodeBlockProps won’t surface a missing branch here at compile time.

Consider tightening this to the same union:

-interface CodeBlockProps {
+interface CodeBlockProps {
   children: string;
-  language?:
-    | 'graphql'
-    | 'typescript'
-    | 'javascript'
-    | 'swift'
-    | 'kotlin'
-    | 'dart'
-    | 'xml';
+  language?: CodeLanguage;
 }
+
+type CodeLanguage =
+  | 'graphql'
+  | 'typescript'
+  | 'javascript'
+  | 'swift'
+  | 'kotlin'
+  | 'dart'
+  | 'xml';
...
-function highlightCode(element: HTMLElement, language: string) {
+function highlightCode(element: HTMLElement, language: CodeLanguage) {

This keeps implementation the same but gives you better compiler help if you add more languages later.

Also applies to: 35-51, 83-262

packages/docs/src/pages/docs/features/purchase.tsx (1)

580-584: Consider clarifying that the consumable check is illustrative.

The purchase.productId.includes('consumable') pattern is a simple example, but in production, developers should maintain a proper product configuration mapping rather than relying on naming conventions.

Consider adding a brief comment or note that this is simplified for demonstration purposes.

packages/docs/src/pages/docs/lifecycle/subscription.tsx (1)

29-132: Consider extracting repeated inline styles to CSS classes.

The inline styles are repeated across multiple table rows and cells. While this works, extracting to CSS classes (e.g., using the existing doc-table class pattern seen in other files) would improve maintainability.

This is a low-priority suggestion since the current approach is functional.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe1dc88 and 1492dee.

📒 Files selected for processing (26)
  • packages/docs/src/components/AnchorLink.tsx (2 hunks)
  • packages/docs/src/components/CodeBlock.tsx (4 hunks)
  • packages/docs/src/components/LanguageTabs.tsx (1 hunks)
  • packages/docs/src/components/PlatformTabs.tsx (2 hunks)
  • packages/docs/src/components/SearchModal.tsx (1 hunks)
  • packages/docs/src/hooks/useScrollToHash.ts (2 hunks)
  • packages/docs/src/pages/docs.tsx (8 hunks)
  • packages/docs/src/pages/docs/apis.tsx (43 hunks)
  • packages/docs/src/pages/docs/errors.tsx (5 hunks)
  • packages/docs/src/pages/docs/events.tsx (7 hunks)
  • packages/docs/src/pages/docs/features.tsx (0 hunks)
  • packages/docs/src/pages/docs/features/external-purchase.tsx (15 hunks)
  • packages/docs/src/pages/docs/features/offer-code-redemption.tsx (1 hunks)
  • packages/docs/src/pages/docs/features/purchase.tsx (1 hunks)
  • packages/docs/src/pages/docs/features/subscription-offers.tsx (1 hunks)
  • packages/docs/src/pages/docs/features/subscription-upgrade-downgrade.tsx (18 hunks)
  • packages/docs/src/pages/docs/lifecycle/index.tsx (2 hunks)
  • packages/docs/src/pages/docs/lifecycle/subscription.tsx (1 hunks)
  • packages/docs/src/pages/docs/updates/announcements.tsx (1 hunks)
  • packages/docs/src/pages/docs/updates/notes.tsx (3 hunks)
  • packages/docs/src/pages/docs/updates/versions.tsx (1 hunks)
  • packages/docs/src/pages/home.tsx (1 hunks)
  • packages/docs/src/pages/tutorials.tsx (5 hunks)
  • packages/docs/src/styles/base.css (0 hunks)
  • packages/docs/src/styles/components.css (2 hunks)
  • packages/docs/src/styles/dark-mode.css (1 hunks)
💤 Files with no reviewable changes (2)
  • packages/docs/src/styles/base.css
  • packages/docs/src/pages/docs/features.tsx
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-10-18T05:46:51.596Z
Learnt from: hyochan
Repo: hyodotdev/openiap PR: 17
File: packages/google/openiap/src/main/java/dev/hyo/openiap/store/OpenIapStore.kt:620-629
Timestamp: 2025-10-18T05:46:51.596Z
Learning: In packages/google/openiap/src/main/java/**/*.kt (Android-only package): DO NOT add Android suffix to function names, even for Android-specific APIs. Exception: Only use Android suffix for cross-platform API types (e.g., ProductAndroid, PurchaseAndroid) that contrast with iOS types. Examples of correct naming: isHorizonEnvironment(context: Context), buildModule(context: Context), acknowledgePurchase(), consumePurchase().

Applied to files:

  • packages/docs/src/pages/docs/features/subscription-offers.tsx
  • packages/docs/src/pages/docs/features/external-purchase.tsx
  • packages/docs/src/pages/docs/apis.tsx
📚 Learning: 2025-11-22T19:30:03.876Z
Learnt from: hyochan
Repo: hyodotdev/openiap PR: 46
File: packages/docs/src/pages/docs/types.tsx:2210-2238
Timestamp: 2025-11-22T19:30:03.876Z
Learning: In the OpenIAP SDK, the IAPKit verification endpoint is handled internally using a default base URL. Users no longer need to provide an `endpoint` field in `RequestVerifyPurchaseWithIapkitProps` - the SDK automatically routes to the correct IAPKit `/purchase/verify` endpoint.

Applied to files:

  • packages/docs/src/pages/docs/features/external-purchase.tsx
  • packages/docs/src/pages/docs/apis.tsx
🧬 Code graph analysis (6)
packages/docs/src/pages/docs/lifecycle/subscription.tsx (2)
packages/gql/src/generated/types.ts (1)
  • Subscription (782-794)
packages/docs/src/hooks/useScrollToHash.ts (1)
  • useScrollToHash (4-28)
packages/docs/src/pages/docs/features/offer-code-redemption.tsx (1)
packages/docs/src/hooks/useScrollToHash.ts (1)
  • useScrollToHash (4-28)
packages/docs/src/pages/docs/features/subscription-offers.tsx (1)
packages/docs/src/hooks/useScrollToHash.ts (1)
  • useScrollToHash (4-28)
packages/docs/src/pages/docs/features/purchase.tsx (2)
packages/gql/src/generated/types.ts (1)
  • Purchase (429-429)
packages/docs/src/hooks/useScrollToHash.ts (1)
  • useScrollToHash (4-28)
packages/docs/src/pages/docs/apis.tsx (2)
packages/google/openiap/src/main/java/dev/hyo/openiap/Types.kt (1)
  • code (1152-1174)
packages/gql/src/generated/Types.kt (1)
  • code (1214-1236)
packages/docs/src/pages/tutorials.tsx (1)
packages/docs/src/hooks/useScrollToHash.ts (1)
  • useScrollToHash (4-28)
⏰ 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: Test Android
🔇 Additional comments (45)
packages/docs/src/components/SearchModal.tsx (1)

372-380: External Purchase doc path update looks consistent

The new /docs/features/external-purchase path aligns with the features namespace; as long as the route exists, this keeps search results in sync with the new docs structure.

packages/docs/src/pages/home.tsx (1)

19-35: Versions badge now targets updates/versions correctly

Updating the link to /docs/updates/versions keeps the home hero in sync with the new updates namespace; no issues from a routing perspective.

packages/docs/src/pages/docs/updates/announcements.tsx (1)

1-4: useScrollToHash import depth matches file location

The updated relative path (../../../hooks/useScrollToHash) correctly reflects this file’s nesting under pages/docs/updates; hook usage remains unchanged and looks good.

packages/docs/src/pages/docs/updates/notes.tsx (1)

1-4: Notes page wiring and external purchase link look correct

The deeper import paths for useScrollToHash and CodeBlock, the Notes component rename/export, and the updated External Purchase link (/docs/features/external-purchase) all align with the new docs layout and hash-scrolling behavior.

Also applies to: 56-60, 393-393

packages/docs/src/pages/docs/updates/versions.tsx (1)

1-3: Import path adjustments are consistent with new directory depth

Pointing AnchorLink, useScrollToHash, and GQL_RELEASE to ../../../... correctly matches the file’s nesting under pages/docs/updates; runtime behavior is unchanged.

packages/docs/src/pages/docs/lifecycle/index.tsx (1)

2-4: Lifecycle imports and new Subscription cross‑link are aligned

The deeper imports for CodeBlock, AnchorLink, and useScrollToHash match the file’s location, and the added link to /docs/lifecycle/subscription is a good navigational cue for platform‑specific subscription details.

Also applies to: 215-218

packages/docs/src/styles/components.css (1)

231-339: LanguageTabs and alert-card styles look consistent

The new .language-tabs* and .alert-card* styles align well with the existing PlatformTabs and info-note patterns. Class naming and layout choices are clear and cohesive; no functional or maintainability concerns from the CSS side.

packages/docs/src/pages/docs/features/subscription-upgrade-downgrade.tsx (2)

262-621: Multi-language upgrade/downgrade docs read well and are consistent

The new LanguageTabs-based structure for the iOS and Android upgrade/downgrade sections is clear and consistent across TypeScript, Swift, Kotlin, and Dart. The narrative around pendingUpgradeProductId, autoRenewPreference, and Android replacement modes is coherent, and the per-language samples line up with each other conceptually.

No structural or React-level issues spotted with the way LanguageTabs/PlatformTabs are wired here.

Also applies to: 661-875, 1045-1548


818-835: Unable to verify—file not found in repository; technical concerns are valid but version-dependent

I conducted extensive searches across the repository and cannot locate the file packages/docs/src/pages/docs/features/subscription-upgrade-downgrade.tsx. Without access to the actual code at the specified line ranges (818–835, 1089–1112, 1225–1248, 1491–1545), I cannot confirm the specific issues described.

However, the underlying Dart null-safety concerns are technically valid:

  • firstOrNull availability: Requires either Dart 3.0+ (built-in via dart:core) or package:collection for earlier versions. If the documentation does not specify the minimum Dart version or note the dependency, this ambiguity should be addressed.
  • firstWhere without orElse: Will throw if no match is found; a subsequent null-check provides no protection.
  • firstWhere(..., orElse: () => null) with non-nullable element types: Invalid under strict null-safety; must use nullable collection types or firstWhereOrNull.

The review's recommendation—to either document the required Dart version / dependencies or rewrite using plain Dart constructs—is sound and would improve portability.

To proceed:

  • Confirm the file path or verify the code exists on the PR branch
  • Check the target Dart version in the repository's analysis options or pubspec.yaml
  • Verify whether package:collection is declared as a dependency
packages/docs/src/pages/docs/errors.tsx (2)

21-52: PurchaseError multi-language definitions are aligned

The new LanguageTabs block for PurchaseError keeps the structure consistent across TypeScript, Swift, Kotlin, and Dart (code/message/productId). The per-language declarations are idiomatic and match the textual description above.


501-656: ErrorCode / OpenIapError / IAPError enums look consistent across languages

The unified error-code section now presents TypeScript’s string enum alongside Swift/Kotlin/Dart enums with matching conceptual values. Naming follows each language’s conventions while preserving the same set of cases, which should help readers map errors between platforms.

Additionally, please double-check that the updated link to the updates page (/docs/updates/notes at line 732) matches an existing route in the docs app to avoid broken navigation.

packages/docs/src/pages/tutorials.tsx (1)

1-6: AnchorLink + useScrollToHash integration looks solid

Using AnchorLink for the section headings and invoking useScrollToHash() brings the Tutorials page in line with the rest of the docs’ hash-based navigation. IDs are clear (setups, news, getting-started, verify-purchase), and this should play nicely with the updated scroll behavior logic.

Also applies to: 23-26, 39-42, 115-118, 141-144

packages/docs/src/components/AnchorLink.tsx (1)

17-33: I'll verify the critical issue about the scrollIntoView behavior type. Let me start by examining the file and checking TypeScript type definitions.
<function_calls>
<invoke_name>shell</invoke_name>

#!/bin/bash

Locate and examine the AnchorLink.tsx file

find . -name "AnchorLink.tsx" -type f | head -5

</invoke_name>
</function_calls>
<function_calls>
<invoke_name>web_search
ScrollBehavior 'instant' TypeScript DOM types valid
</invoke_name>
</function_calls>

Wait for the results to verify the type correctness of the 'instant' behavior value.

packages/docs/src/hooks/useScrollToHash.ts (1)

9-22: I'll verify the scroll behavior issue in the useScrollToHash.ts file. Let me start by examining the file and checking for type-checking errors related to the 'instant' behavior value.
<function_calls>


#!/bin/bash

Locate and examine the useScrollToHash.ts file

find . -name "useScrollToHash.ts" -type f 2>/dev/null


</function_calls>
<function_calls>


#!/bin/bash

Read the file to verify the content

cat -n packages/docs/src/hooks/useScrollToHash.ts


</function_calls>
<function_calls>

DOM ScrollBehavior type definition allowed values 'auto' 'smooth' 'instant'

</function_calls>

packages/docs/src/pages/docs/features/purchase.tsx (4)

1-11: LGTM - Clean component setup with appropriate imports.

The component follows the established documentation page pattern with proper imports for navigation hooks and UI components.


46-58: Excellent warning placement for critical IAP requirements.

The alert card effectively communicates the consequences of incomplete transactions on both platforms. This is essential information that developers often miss.


694-700: Well-structured complete example section.

The comprehensive examples demonstrate production-ready patterns for each platform, including proper state management (React Context, ObservableObject, StateFlow, ChangeNotifier).


1068-1114: Excellent troubleshooting reference.

The table format clearly maps issues to causes and solutions. This will save developers significant debugging time.

packages/docs/src/pages/docs/features/offer-code-redemption.tsx (3)

1-9: Clean component setup with appropriate imports.

Uses the established pattern with PlatformTabs for platform-specific content and LanguageTabs for multi-language code samples.


57-149: Well-organized platform-specific documentation.

The nested structure of PlatformTabs > LanguageTabs effectively handles the complexity of platform-specific features with multi-language support. The "iOS-only" placeholders in Kotlin tabs correctly indicate platform restrictions.


291-390: Android implementation correctly documents the deep link approach.

Since Google Play lacks a native in-app redemption API, the documentation correctly shows the URL-based approach using platform-appropriate methods (Linking, Intent, url_launcher).

packages/docs/src/pages/docs/features/subscription-offers.tsx (4)

1-8: Clean component setup following established patterns.


31-68: Clear platform comparison with actionable guidance.

The table effectively communicates the key difference: iOS auto-applies offers while Android requires explicit offer tokens. The tip about fetching products first prevents a common mistake.


450-460: Excellent developer experience - showing the exact error message.

Including the actual error message developers will encounter helps them quickly identify and resolve this common Android subscription issue.


744-808: Comprehensive offer selection logic.

The selectOffer function demonstrates proper filtering by offer type, which is essential for Android subscription purchases. The pattern is reusable across different use cases.

packages/docs/src/pages/docs/lifecycle/subscription.tsx (4)

1-8: Clean component setup with appropriate imports.

Uses Accordion for collapsible content sections which improves readability for detailed documentation.


63-131: Accurate platform data availability comparison.

The table correctly shows that iOS provides rich client-side subscription data via StoreKit 2, while Android requires server-side API calls for most subscription details. This is crucial information for developers planning their architecture.


255-326: Clear lifecycle flow documentation.

The pseudo-code style flow diagrams effectively communicate the step-by-step process for handling subscriptions at different lifecycle points. The platform-specific tabs highlight important differences.


708-740: Excellent edge case documentation.

The refund scenario clearly demonstrates why server-side validation is essential. The before/after comparison effectively communicates the risk of relying solely on client-side data.

packages/docs/src/pages/docs.tsx (3)

6-21: Clean import organization for new documentation pages.

The new imports are organized logically:

  • Line 6: Subscription under lifecycle
  • Lines 11-15: Feature pages
  • Lines 19-21: Updates pages

All paths match the new file structure.


80-87: Good use of MenuDropdown for expandable navigation.

The Life Cycle section now uses MenuDropdown to accommodate the new Subscription sub-page, allowing for future expansion of the lifecycle documentation.


224-256: Route definitions correctly match navigation structure.

All new routes are properly defined:

  • lifecycle/subscription for the new subscription lifecycle page
  • features/* for all feature documentation pages
  • updates/* for announcements, notes, and versions

The routing structure is clean and follows React Router patterns.

packages/docs/src/pages/docs/features/external-purchase.tsx (3)

1-6: LGTM! Clean import organization.

The updated imports properly include the new LanguageTabs component alongside existing dependencies. The relative path structure is consistent with the file's location within the features subdirectory.


100-269: Well-structured multi-language presentation for iOS external purchase flow.

The LanguageTabs implementation correctly presents equivalent code samples across TypeScript, Swift, Kotlin (for KMP iOS targets), and Dart. The code logic is consistent across all languages, and the Kotlin sample appropriately notes it's for iOS targets in Kotlin Multiplatform.


563-749: Correct omission of Swift tab for Android-only APIs.

The Android Alternative Billing section appropriately includes only TypeScript, Kotlin, and Dart tabs since Swift is not applicable for Android-specific billing APIs.

packages/docs/src/pages/docs/events.tsx (4)

23-56: Correct platform-specific event type definitions.

The enum definitions appropriately reflect platform capabilities:

  • Swift omits userChoiceBillingAndroid (Android-only)
  • Kotlin omits promotedProductIOS (iOS-only)
  • TypeScript and Dart include all events for cross-platform awareness

94-183: Comprehensive listener examples across all languages.

The purchase updated listener examples demonstrate proper patterns for each platform:

  • TypeScript: subscription-based cleanup
  • Swift: AsyncSequence and Combine approaches
  • Kotlin: Flow and callback approaches
  • Dart: Stream subscription with cancel

399-509: Good platform availability documentation for Promoted Product event.

The Kotlin tab correctly indicates "iOS only - not available on Android" and the Dart example includes a comment noting it will only fire on iOS. This prevents developer confusion about platform-specific events.


546-650: Correct handling of Android-only User Choice Billing event.

The Swift tab appropriately shows "Android only - not available on iOS" and the usage examples correctly omit Swift implementation. The TypeScript, Kotlin, and Dart examples are consistent in structure and demonstrate the proper token reporting workflow.

packages/docs/src/pages/docs/apis.tsx (6)

4-6: LGTM! Proper import addition.

The LanguageTabs import is correctly added alongside existing component imports.


65-176: Clear multi-language API documentation for initConnection.

The function signatures and usage examples correctly show platform-specific differences:

  • TypeScript uses string literals for mode selection
  • Swift notes alternative billing is Android-only
  • Kotlin uses enum values with proper naming conventions
  • Dart follows Dart enum conventions

443-523: Comprehensive iOS External Purchase Links documentation.

The 3-step external purchase flow is well documented across all languages with clear step-by-step comments. The Kotlin sample correctly notes that external purchase is iOS-only and suggests using alternative billing APIs for Android targets.


926-947: Good use of styled alert card for new feature highlight.

The .alert-card--success styling effectively draws attention to the new iOS renewal status information feature.


1509-1558: Well-documented new iOS external purchase APIs.

The three new APIs (canPresentExternalPurchaseNoticeIOS, presentExternalPurchaseNoticeSheetIOS, presentExternalPurchaseLinkIOS) are properly documented with:

  • Clear function signatures
  • Return type definitions
  • iOS version requirements
  • Links to related type documentation

1701-1791: Complete Alternative Billing flow example across platforms.

The 3-step flow example is consistent across TypeScript, Kotlin, and Dart, correctly demonstrating:

  1. Availability check
  2. User dialog presentation
  3. Token creation after payment

Swift is appropriately omitted since this is Android-specific functionality.

@hyochan hyochan merged commit a27e459 into main Nov 26, 2025
5 checks passed
@hyochan hyochan deleted the docs/lifecycle-subs-improve-details branch November 26, 2025 05:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📖 documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant