Skip to content

Commit 7df9d1b

Browse files
committed
Merge branch 'ADP-4469' into develop
# Conflicts: # versioned_docs/version-3.0/autopilot-how-it-works.md
2 parents cd5ed13 + 0519e42 commit 7df9d1b

25 files changed

Lines changed: 414 additions & 120 deletions

src/components/SidebarMenu/index.jsx

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,41 @@ import { isMobileSdkDocument, getCorrespondingDocId } from '../../lib/sidebarMap
66

77

88
export default function SidebarMenu() {
9-
9+
1010
const router = useHistory();
1111
const { pathname } = router.location;
1212
const activeDocContext = useActiveDocContext();
1313
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
1414

15-
15+
1616
// Debug: log the pathname and active context
17-
17+
1818
// Define platform options with correct paths
1919
const platforms = [
2020
{ name: 'iOS', path: '/docs/ios-sdk-overview', sidebarId: 'sdkios' },
2121
{ name: 'Android', path: '/docs/android-sdk-overview', sidebarId: 'sdkandroid' },
2222
{ name: 'Flutter', path: '/docs/flutter-sdk-overview', sidebarId: 'sdkflutter' },
2323
{ name: 'React Native', path: '/docs/react-native-sdk-overview', sidebarId: 'sdkreactnative' },
2424
{ name: 'Unity', path: '/docs/unity-sdk-overview', sidebarId: 'sdkunity' },
25-
{ name: 'Kotlin Multiplatform', path: '/docs/kmp-sdk-overview', sidebarId: 'sdkkmp' },
26-
{ name: 'Capacitor (Beta)', path: '/docs/capacitor-sdk-overview', sidebarId: 'sdkcapacitor' },
25+
{ name: 'Kotlin Multiplatform', path: '/docs/kmp-sdk-overview', sidebarId: 'sdkkmp' },
26+
{ name: 'Capacitor (Beta)', path: '/docs/capacitor-sdk-overview', sidebarId: 'sdkcapacitor' },
2727
];
28-
28+
2929
// Try to detect current platform from active sidebar
3030
let currentPlatform = platforms[0]; // Default to iOS
3131

32-
32+
3333
if (activeDocContext && activeDocContext.sidebar) {
3434
const sidebarId = activeDocContext.sidebar;
3535
const detectedPlatform = platforms.find(p => p.sidebarId === sidebarId);
3636
if (detectedPlatform) {
3737
currentPlatform = detectedPlatform;
3838
}
3939
}
40-
40+
4141
// Fallback to URL-based detection
4242
if (currentPlatform === platforms[0]) {
43-
43+
4444
// More specific URL-based detection
4545
if (pathname.includes('react-native-sdk') || pathname.includes('reactnative')) {
4646
currentPlatform = platforms.find(p => p.sidebarId === 'sdkreactnative');
@@ -53,9 +53,9 @@ export default function SidebarMenu() {
5353
} else if (pathname.includes('unity-sdk') || pathname.includes('unity')) {
5454
currentPlatform = platforms.find(p => p.sidebarId === 'sdkunity');
5555
} else if (pathname.includes('capacitor-sdk') || pathname.includes('capacitor')) {
56-
currentPlatform = platforms.find(p => p.sidebarId === 'sdkcapacitor');
56+
currentPlatform = platforms.find(p => p.sidebarId === 'sdkcapacitor');
5757
} else if (pathname.includes('kmp') || pathname.includes('kotlin-multiplatform')) {
58-
currentPlatform = platforms.find(p => p.sidebarId === 'sdkkmp');
58+
currentPlatform = platforms.find(p => p.sidebarId === 'sdkkmp');
5959
} else {
6060
// Fallback to the old logic
6161
currentPlatform = platforms.find(p => {
@@ -69,11 +69,11 @@ export default function SidebarMenu() {
6969
const handlePlatformChange = (platform) => {
7070
// Get the current document ID
7171
const currentDocId = activeDocContext?.activeDoc?.id;
72-
72+
7373
if (currentDocId) {
7474
// Try to find the corresponding document in the target platform
7575
const correspondingDocId = getCorrespondingDocId(currentDocId, platform.sidebarId);
76-
76+
7777
if (correspondingDocId) {
7878
// Navigate to the corresponding document
7979
router.push(`/docs/${correspondingDocId}`);
@@ -87,27 +87,27 @@ export default function SidebarMenu() {
8787
}
8888
};
8989

90-
90+
9191
// Get the current document ID from activeDocContext
9292
const currentDocId = activeDocContext?.activeDoc?.id;
9393

94-
94+
9595
// Check if current document belongs to a mobile SDK sidebar
9696
const isMobileSdkPage = currentDocId && isMobileSdkDocument(currentDocId);
9797

98-
98+
9999
// Also check if we're on a platform overview page by URL
100100
const isOverviewPage = pathname.includes('-sdk-overview');
101-
101+
102102
// Show switcher if it's a mobile SDK page OR an overview page
103103
const shouldShowSwitcher = isMobileSdkPage || isOverviewPage;
104104

105105
// Add/remove CSS class to sidebar container based on switcher visibility
106106
useEffect(() => {
107-
107+
108108
// Find the sidebar container
109109
const sidebarContainer = document.querySelector('.theme-doc-sidebar-container');
110-
110+
111111
if (sidebarContainer) {
112112
if (shouldShowSwitcher) {
113113
sidebarContainer.classList.add('platform-switcher-visible');
@@ -130,16 +130,13 @@ export default function SidebarMenu() {
130130
return null;
131131
}
132132

133-
133+
134134
return (
135135
<div style={{
136136
width: '100%',
137137
padding: '24px 16px 8px 16px',
138138
background: '#f8f9fa',
139139
borderBottom: '1px solid #e9ecef',
140-
position: 'sticky',
141-
top: '0',
142-
zIndex: '10',
143140
flexShrink: 0,
144141
boxShadow: '0 1px 3px rgba(0,0,0,0.1)'
145142
}}>
@@ -148,14 +145,14 @@ export default function SidebarMenu() {
148145
alignItems: 'center',
149146
gap: '8px'
150147
}}>
151-
<div style={{
152-
color: '#495057',
153-
fontWeight: '600',
154-
fontSize: '15px',
155-
whiteSpace: 'nowrap'
156-
}}>
157-
Platform:
158-
</div>
148+
<div style={{
149+
color: '#495057',
150+
fontWeight: '600',
151+
fontSize: '15px',
152+
whiteSpace: 'nowrap'
153+
}}>
154+
Platform:
155+
</div>
159156
<div style={{ position: 'relative', flex: 1 }}>
160157
<button
161158
style={{
@@ -191,7 +188,7 @@ export default function SidebarMenu() {
191188
<path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
192189
</svg>
193190
</button>
194-
191+
195192
{isDropdownOpen && (
196193
<div style={{
197194
position: 'absolute',

src/css/custom.css

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,13 +1040,5 @@ details code {
10401040
}
10411041

10421042
/* Ensure sidebar remains scrollable */
1043-
.theme-doc-sidebar-container.platform-switcher-visible [class*="sidebarViewport"] {
1044-
overflow-y: auto !important;
1045-
height: 100% !important;
1046-
}
10471043

1048-
.theme-doc-sidebar-container.platform-switcher-visible [class*="sidebar_src-theme-DocSidebar-Desktop"] {
1049-
overflow-y: auto !important;
1050-
height: 100% !important;
1051-
}
10521044

src/theme/DocSidebar/Desktop/index.jsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }) {
2525
>
2626
{hideOnScroll && <Logo tabIndex={-1} className={styles.sidebarLogo} />}
2727
<SidebarMenu />
28-
<Content path={path} sidebar={sidebar} />
28+
<div className={styles.contentWrapper}>
29+
<Content path={path} sidebar={sidebar} />
30+
</div>
2931
{hideable && <CollapseButton onClick={onCollapse} />}
3032
</div>
3133
);

src/theme/DocSidebar/Desktop/styles.module.css

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
.sidebar {
22
display: flex;
33
flex-direction: column;
4-
height: 100%;
4+
height: auto !important;
5+
bottom: 0;
56
width: var(--doc-sidebar-width);
67
position: fixed;
78
top: 0;
@@ -11,11 +12,13 @@
1112
border-right: 1px solid var(--ifm-toc-border-color);
1213
transition: transform var(--ifm-transition-fast) ease;
1314
padding-top: 45px;
15+
box-sizing: border-box;
1416
}
1517

1618
.sidebarWithHideableNavbar {
1719
top: var(--ifm-navbar-height);
18-
height: calc(100% - var(--ifm-navbar-height));
20+
height: auto !important;
21+
bottom: 0;
1922
}
2023

2124
.sidebarHidden {
@@ -37,4 +40,18 @@
3740
height: 2rem;
3841
}
3942

43+
.contentWrapper {
44+
flex: 1;
45+
min-height: 0;
46+
display: flex;
47+
flex-direction: column;
48+
}
4049

50+
/* Target the inner menu to make it scrollable */
51+
.contentWrapper :global(.menu) {
52+
flex: 1;
53+
min-height: 0;
54+
overflow-y: auto;
55+
padding-bottom: 300px !important;
56+
box-sizing: border-box;
57+
}

versioned_docs/version-3.0/autopilot-how-it-works.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ description: "Understand the logic behind the Growth Autopilot and trust us to g
44
metadataTitle: "Growth Autopilot | Adapty Docs"
55
keywords: ['autopilot', 'growth autopilot']
66
---
7+
import ZoomImage from '@site/src/components/ZoomImage';
78

89
[Growth Autopilot](autopilot.md) helps you figure out which experiments to run based on your actual performance data and how similar apps in your market are doing. Instead of guessing what might work, you get specific recommendations for tests that are more likely to improve your results.
910

@@ -36,7 +37,9 @@ This gives Autopilot a baseline to work from before suggesting any changes.
3637
We don't use your app's performance data to train recommendations for other apps. Your data stays private.
3738
:::
3839

39-
#### Market benchmark data
40+
<ZoomImage id="app-analysis.webp" width="700px" />
41+
42+
#### Competitor data
4043

4144
Autopilot compares your setup with similar apps in your market using public information like pricing, subscription structures, and common patterns in your category. This is based on third-party and public data, not private metrics from other Adapty clients.
4245

@@ -46,12 +49,16 @@ This way, you're testing strategies that already work for apps like yours, not j
4649
Autopilot selects relevant competitors automatically based on what you can realistically compete with. We generally recommend sticking with these suggestions rather than adding apps that are too far ahead or too far behind. If your app falls into several categories, you might want to adjust the list to focus on the most relevant market segment.
4750
:::
4851

52+
<ZoomImage id="competitors-analysis.webp" width="700px" />
53+
4954
#### Industry benchmarks
5055

5156
Autopilot also uses category-level data to show how you compare to the industry average. This data is anonymized and aggregated, not tied to specific apps.
5257

5358
For example, your conversion funnel might be compared against the average for apps in your category. This helps you see if you're underperforming, doing about average, or already ahead of the curve.
5459

60+
<ZoomImage id="industry-benchmarks.webp" width="700px" />
61+
5562
## How Autopilot decides what to recommend
5663

5764
Autopilot creates a sequence of experiments to improve your paywall step by step. Instead of testing everything at once, it focuses on one change at a time so you can see what actually works.
@@ -74,9 +81,19 @@ Here's how it works:
7481

7582
Autopilot only suggests tests you can launch with your existing products and setup, or with small changes like creating a new product or adjusting a price. The goal is to keep testing fast and manageable.
7683

84+
5. **Show you the reasoning**
85+
86+
For each recommendation, Autopilot provides a clear hypothesis that explains exactly why this test is worth running. You'll see how your current metrics compare to competitors and industry averages, what the opportunity is, and which key metrics we expect to improve.
87+
7788
This turns experimentation into a repeatable process where each test teaches you something and moves you toward a more effective paywall.
7889

90+
91+
<ZoomImage id="growth-plan.webp" width="700px" />
92+
7993
## What happens after you complete the experiments
8094

8195
Once you finish all the recommended experiments and see an increase in revenue, your work isn't done. After some time with your new setup, you can rerun the analysis and start a fresh round of experiments. You might even choose to compete with more advanced competitors now that you've optimized your baseline. This iterative approach helps you keep maximizing your revenue as your app grows and the market evolves.
8296

97+
:::tip
98+
More features are coming! Expect even smarter suggestions, an idea library to explore proven strategies, and the ability to launch experiments in one click. Autopilot will keep getting better at helping you grow.
99+
:::

versioned_docs/version-3.0/autopilot.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,21 @@ The recommendations page will show you the target number of subscribers and the
161161
margin: '0 auto' /* center alignment */
162162
}}
163163
/>
164+
</Zoom>
165+
166+
## Why will it work?
167+
168+
Every recommendation comes with a clear hypothesis that explains the reasoning behind it. You'll see how your current metrics stack up against competitors and industry averages, what opportunity we've identified, and which key metrics the test is expected to improve.
169+
170+
For a detailed look at how Autopilot analyzes your growth strategy and which data sources it uses to create recommendations, check out [our article](autopilot-how-it-works.md).
171+
172+
<Zoom>
173+
<img src={require('./img/hypothesis.png').default}
174+
style={{
175+
border: '1px solid #727272', /* border width and color */
176+
width: '700px', /* image width */
177+
display: 'block', /* for alignment */
178+
margin: '0 auto' /* center alignment */
179+
}}
180+
/>
164181
</Zoom>
750 KB
Loading
823 KB
Loading
82.2 KB
Loading
698 KB
Loading

0 commit comments

Comments
 (0)