SDK ์ฐ๋
Hackle React SDK๋ React 16.8 ์ด์ ๋ฒ์ ์ ์ง์ํฉ๋๋ค.
React SDK๋ JavaScript SDK ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋์ํฉ๋๋ค.
1. ์์กด์ฑ ์ถ๊ฐ
npm install --save @hackler/react-sdkyarn add @hackler/react-sdk2. SDK ์ด๊ธฐํ
SDK๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ๋ฐ๋์ HackleReactSDKClient ๋ฅผ ์ด๊ธฐํ ํด์ผ ํฉ๋๋ค.
HackleReactSDKClient๋ SDK์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํ ๋ฉ์๋๋ค์ ์ ๊ณตํ๋ ํด๋์ค์ ๋๋ค.- SDK ํค๋ ํตํด ์๋น์ค์ ๋์๋ณด๋ ์์ ์์นํ SDK ์ฐ๋ ์ ๋ณด์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
์ดํ๋ฆฌ์ผ์ด์ ์ด๊ธฐํ ๋จ๊ณ์ ํตํด ์๋ฒ์ ๋ฐ์ดํฐ ๋๊ธฐํ๋ฅผ ์ํ ํต์ ์ ์งํํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ด ์๊ฐ์ ์ ๋ฐ๋ฆฌ ์ด์ ๋ถ๊ณผํฉ๋๋ค. ๋๊ธฐํ๊ฐ ์๋ฃ๋๋ฉด ์ฆ์ ๋ ๋๋ง์ด ์งํ๋ฉ๋๋ค.
Google Tag Manager (GTM) ์ฌ์ฉ์ ์ฃผ์ ์ฌํญGTM์ ์ฌ์ฉํ์ฌ ์ฐ๋์ ์งํํ ๊ฒฝ์ฐ, Hackle SDK ์ด๊ธฐํ๋ฅผ ํ๊ณ , SDK๋ฅผ GTM ์์ ์ ๊ทผํ ์ ์๋๋ก window์ ์ถ๊ฐ ์ ์ธ์ด ํ์ํฉ๋๋ค.
import { createInstance, HackleProvider } from "@hackler/react-sdk";
// YOUR_BROWSER_SDK_KEY ์๋ฆฌ์ SDK ํค๋ฅผ ๋ฃ์ต๋๋ค.
const hackleClient = createInstance("YOUR_BROWSER_SDK_KEY")
ReactDOM.render(
<HackleProvider hackleClient={hackleClient}>
<YourApp />
</HackleProvider>,
document.getElementById('root')
);
// GTM ์ฐ๋ ์ ์ถ๊ฐ script
window.hackleClient = hackleClientimport {createInstance, HackleProvider} from "@hackler/react-sdk";
// YOUR_BROWSER_SDK_KEY ์๋ฆฌ์ SDK ํค๋ฅผ ๋ฃ์ต๋๋ค.
const hackleClient = createInstance("YOUR_BROWSER_SDK_KEY")
function MyApp({Component, pageProps}) {
return (
<HackleProvider hackleClient={hackleClient} supportSSR>
<Component {...pageProps} />
</HackleProvider>
)
}
export default MyAppimport {createInstance, HackleProvider} from "@hackler/react-sdk";
// YOUR_BROWSER_SDK_KEY ์๋ฆฌ์ SDK ํค๋ฅผ ๋ฃ์ต๋๋ค.
const hackleClient = createInstance("YOUR_BROWSER_SDK_KEY")
function App() {
return (
<HackleProvider hackleClient={hackleClient} supportSSR>
<YourApp />
</HackleProvider>
)
}
export default App์ด๊ธฐํ ์ค์ ์ ๋ณด
์ค์ ์ ๋ณด๋ฅผ ํฌํจํ์ฌ SDK๋ฅผ ์ด๊ธฐํ ํ ์ ์์ต๋๋ค.
๋๋ฒ๊ทธ ๋ชจ๋
debug ์ต์
์ true ๋ก ์ค์ ํ์ฌ ํ์ฑํ ํฉ๋๋ค. ๋๋ฒ๊ทธ ๋ชจ๋๋ฅผ ํ์ฑํ ์ํค๋ฉด ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ํ ๋ก๊ทธ๊ฐ ์ฝ์์ ์ถ๋ ฅ๋ฉ๋๋ค.
import { createInstance, HackleProvider } from "@hackler/react-sdk";
// ์ค์ ์ ๋ณด๋ฅผ ํฌํจํ์ฌ ์ด๊ธฐํ
const config = {
debug: true
};
const hackleClient = createInstance("YOUR_BROWSER_SDK_KEY", config);
ReactDOM.render(
<HackleProvider hackleClient={hackleClient}>
<YourApp />
</HackleProvider>,
document.getElementById('root')
);import {createInstance, HackleProvider} from "@hackler/react-sdk";
// ์ค์ ์ ๋ณด๋ฅผ ํฌํจํ์ฌ ์ด๊ธฐํ
const config = {
debug: true
};
const hackleClient = createInstance("YOUR_BROWSER_SDK_KEY", config);
function MyApp({Component, pageProps}) {
return (
<HackleProvider hackleClient={hackleClient} supportSSR>
<Component {...pageProps} />
</HackleProvider>
)
}
export default MyApp๋ชจ๋ ์ค์ ์ต์
key | ๊ธฐ๋ฅ | ๊ธฐ๋ณธ๊ฐ | ์ง์ ๋ฒ์ |
|---|---|---|---|
debug | ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ํ ๋๋ฒ๊ทธ(debug) ๋ก๊ทธ๋ฅผ ์ฝ์(console)์์ ๋ณผ ์ ์์ต๋๋ค. | false | 1.0.0+ |
pollingIntervalMillis | ๋์๋ณด๋์์ ์ค์ ํ ์ ๋ณด๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ๋ฐ์ดํธ ํ ์ ์์ต๋๋ค. ์ต์๊ฐ : 60000 (60์ด) | -1 | 11.1.0+ |
exposureEventDedupIntervalMillis | ๋์ผํ ์ฌ์ฉ์๊ฐ ์ฐ์์ผ๋ก ๋ฐ์์ํจ ๋์ผํ A/B ํ ์คํธ, ๊ธฐ๋ฅํ๋๊ทธ ๋ถ๋ฐฐ๊ฒฐ๊ณผ์ ๋ํ ๋ ธ์ถ ์ด๋ฒคํธ๋ฅผ ์ ๊ฑฐํฉ๋๋ค. ์ต์๊ฐ: 1000 (1์ด) | 36000(1๋ถ / 11.23.0 ๋ฒ์ ์ด์) -1 (์ค๋ณต์ ๊ฑฐ ํ์ง ์์ / 11.23.0 ๋ฒ์ ๋ฏธ๋ง) | 11.1.0+ |
sessionTimeoutMillis | ์ธ์ ๋ง๋ฃ ์๊ฐ์ ์ค์ ํฉ๋๋ค. | 1800000 (30๋ถ) | 11.8.0+ |
devTool | ์ฌ์ฉ์ ํ์์ ์ฌ์ฉํ ์ ์๋๋ก ํฉ๋๋ค. | undefined | 11.13.0+ |
autoOpenDevTool | ์ฌ์ฉ์ ํ์ ๋ฒํผ์ด ์๋์ผ๋ก ๋ํ๋๋๋ก ํ๋ ์ต์ ์ ๋๋ค. | false | 11.13.0+ |
๋์๋ณด๋ ์ค์ ์ ๋ณด ๊ฐฑ์
๋์๋ณด๋ ์ค์ ์ ๋ณด๋ฅผ ๋ช ์์ ์ผ๋ก ๊ฐฑ์ ํ ์ ์์ต๋๋ค.
hackleClient.fetch();ํด๋น ํจ์๋ 60์ด์ ํ๋ฒ ์ ํ์ ์ผ๋ก ํธ์ถํ ์ ์์ต๋๋ค.
3. ์ฌ์ฉ์ ์ค์
์ฌ์ฉ์ ์ ๋ณด๋ฅผ SDK์ ์ค์ ํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ID ์ค์
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๊ฒฝ์ฐ, setUserId ๋ฅผ ํธ์ถํด์ ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ID๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค.
- ๋ก๊ทธ์ธ ์ ํ๋ฒ๋ง ์ค์ ํ๋ฉด ๋ฉ๋๋ค.
- ์ด๋ฏธ ๋ก๊ทธ์ธ์ด ๋์ด์๋ ์ฌ์ฉ์์ ๊ฒฝ์ฐ์๋ ๋ก๊ทธ์ธํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์ค๋ ์์ ์ ํธ์ถํ๋ฉด ๋ฉ๋๋ค.
const userId = ... // ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ID (ํ์๋ฒํธ, ๋ฉค๋ฒ ID ๋ฑ)
hackleClient.setUserId(userId);์ฌ์ฉ์ ์์ฑ ์ค์
์ด๋ฉ์ผ์ฃผ์, ์์น, ๋์ด, ํ์๋ฑ๊ธ๊ณผ ๊ฐ์ ์ ๋ณด๋ฅผ ์ฌ์ฉ์ ์์ฑ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. setUserProperty, setUserProperties ๋ฅผ ํธ์ถํ์ฌ ์ฌ์ฉ์ ์์ฑ์ ์ค์ ํ ์ ์์ต๋๋ค.
import { PropertyOperationsBuilder } from "@hackler/react-sdk"
const operations = new PropertyOperationsBuilder()
.set("age", 42)
.set("grade", "GOLD")
.build();
hackleClient.updateUserProperties(operations);์ฌ์ฉ์ ๋ก๊ทธ์์ ์ ์ฌ์ค์
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์์ ํ ๊ฒฝ์ฐ resetUser๋ฅผ ํธ์ถํด์ ๊ธฐ์กด์ ์ค์ ํ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฆฌ์
ํ ์ ์์ต๋๋ค. ์๋ ์ ๋ณด๊ฐ ๋ฆฌ์
๋ฉ๋๋ค.
- ์ฌ์ฉ์ ID
- ์ฌ์ฉ์ ์์ฑ
hackleClient.resetUser();4. ์ด๋ฒคํธ ์ ์ก
์ฌ์ฉ์๊ฐ ์ํํ๋ ํ๋์ ์ด๋ฒคํธ๋ก ์ ์กํ ์ ์์ต๋๋ค. ์ ์ก๋ ์ด๋ฒคํธ๋ A/B ํ ์คํธ ๋ถ์, ๋ฐ์ดํฐ ๋ถ์ ๋ฑ์ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ๋ค์ด, ์ฌ์ฉ์๊ฐ ๊ตฌ๋งค๋ผ๋ ํ๋์ ํ๋ค๋ฉด ์๋์ ๊ฐ์ด ์ด๋ฒคํธ๋ฅผ ์ ์กํ ์ ์์ต๋๋ค.
// ์ด๋ฒคํธ ์์ง
hackleClient.track('purchase')
// ์ด๋ฒคํธ๋ฅผ ์์ฑ๊ณผ ํจ๊ป ์์ง
const event = {
key: "purchase",
properties: {
amount: 4200,
pay_method: "CARD",
is_discount: false,
product_ids: [42, 43]
}
}
hackleClient.track(event);์ ์กํ ์ด๋ฒคํธ ํ์ธํ๊ธฐ
๋์๋ณด๋ ์ด๋ฒคํธ๊ด๋ฆฌ ๋ฉ๋ด์์ ์ ์กํ ์ด๋ฒคํธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ฒคํธ ์ ์ก ํ ๋์๋ณด๋์ ํ์๋๊ธฐ๊น์ง ์ผ๋ฐ์ ์ผ๋ก ~60์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค.
5. A/B ํ
์คํธ
์ฌ์ฉ์๋ฅผ ํ
์คํธ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฐฐํ๊ณ ๋ถ๋ฐฐ๋ ๊ฒฐ๊ณผ์ ํด๋นํ๋ ๋ก์ง์ ์์ฑํ์ฌ A/B ํ
์คํธ๋ฅผ ๊ตฌํํฉ๋๋ค.
ํตํด์ด ์ ๊ณตํ๋ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ Hooks API๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์๋ฅผ ํน์ ๊ทธ๋ฃน์ผ๋ก ๋ถ๋ฐฐํ๊ณ ๋ถ๋ฐฐ ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌ ๋ฐ์ ์ ์์ต๋๋ค. ๋ถ๋ฐฐ ์์๋ ์คํ ํค๋ฅผ ์ ๋ฌํด์ผ ํฉ๋๋ค.
์คํํค: ๊ฐ A/B ํ ์คํธ๋ณ๋ก ๊ฐ๊ฒ ๋๋ ๊ณ ์ ๋ฒํธ์ ๋๋ค. A/B ํ ์คํธ๋ฅผ ์์ฑํ๋ฉด ์๋์ผ๋ก ๋ฐ๊ธ๋ฉ๋๋ค.
import {HackleExperiment, HackleVariation} from "@hackler/react-sdk";
function App() {
return (
// ์คํ ํค๊ฐ 42์ธ A/B ํ
์คํธ์์ ์ฌ์ฉ์์๊ฒ ๋
ธ์ถํ ํ
์คํธ ๊ทธ๋ฃน์ ๊ฒฐ์ ํฉ๋๋ค.
// ๊ฒฐ์ ํ์ง ๋ชปํ๋ ์ํฉ์ธ ๊ฒฝ์ฐ ํ
์คํธ ๊ทธ๋ฃน A๋ฅผ ๋ฐํํฉ๋๋ค.
<HackleExperiment experimentKey={42}>
<HackleVariation variation={"A"}>
<AwesomeFeature />
</HackleVariation>
<HackleVariation variation={"B"}>
<SuperAwesomeFeature />
</HackleVariation>
</HackleExperiment>
)
}import {useLoadableVariation, useVariation} from "@hackler/react-sdk";
// ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ
function App() {
// ์คํ ํค๊ฐ 42์ธ A/B ํ
์คํธ์์ ์ฌ์ฉ์์๊ฒ ๋
ธ์ถํ ํ
์คํธ ๊ทธ๋ฃน์ ๊ฒฐ์ ํฉ๋๋ค.
// ๊ฒฐ์ ํ์ง ๋ชปํ๋ ์ํฉ์ธ ๊ฒฝ์ฐ ํ
์คํธ ๊ทธ๋ฃน A๋ฅผ ๋ฐํํฉ๋๋ค.
const variation = useVariation(42)
// ํ ๋น๋ฐ์ ๊ทธ๋ฃน์ ๋ํ ๋ก์ง
if (variation === "A") return <AwesomeFeature />
if (variation === "B") return <SuperAwesomeFeature />
return <AwesomeFeature />
}
// SSR ์ฌ์ฉ ์
function App() {
// ์คํ ํค๊ฐ 42์ธ A/B ํ
์คํธ์์ ์ฌ์ฉ์์๊ฒ ๋
ธ์ถํ ํ
์คํธ ๊ทธ๋ฃน์ ๊ฒฐ์ ํฉ๋๋ค.
// ๊ฒฐ์ ํ์ง ๋ชปํ๋ ์ํฉ์ธ ๊ฒฝ์ฐ ํ
์คํธ ๊ทธ๋ฃน A๋ฅผ ๋ฐํํฉ๋๋ค.
const { isLoading, variation } = useLoadableVariation(42)
// SDK Loading ์ ์ปดํฌ๋ํธ ๋น๋
ธ์ถ
if (isLoading) return null
// ํ ๋น๋ฐ์ ๊ทธ๋ฃน์ ๋ํ ๋ก์ง
if (variation === "A") return <AwesomeFeature />
if (variation === "B") return <SuperAwesomeFeature />
return <AwesomeFeature />
}๋ถ๋ฐฐ ๊ฒฐ๊ณผ ํ์ธํ๊ธฐ
๋์๋ณด๋ A/B ํ ์คํธ์ ์์ธํ์ด์ง์ ์ค์๊ฐ ๋ ธ์ถ ํํฉ ํญ์์ ๋ถ๋ฐฐ๋ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ๋ถ๋ฐฐ ํ ๋์๋ณด๋์ ํ์๋๊ธฐ๊น์ง ์ผ๋ฐ์ ์ผ๋ก ~60์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค.
6. ๊ธฐ๋ฅ ํ๋๊ทธ
๊ธฐ๋ฅ ํ๋๊ทธ๋ ์ผ์ง(on) ์ํ์ ๊บผ์ง(off) ์ํ๊ฐ ์์ต๋๋ค. ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ก์ง์ ์์ฑํ์ฌ ๊ธฐ๋ฅ ํ๋๊ทธ๋ฅผ ๊ตฌํํฉ๋๋ค.
ํตํด์ด ์ ๊ณตํ๋ ์ปดํฌ๋ํธ, Hooks API์ ๊ธฐ๋ฅํ๋๊ทธ ํค๋ฅผ ์ ๋ฌํ์ฌ on/off ๊ฒฐ๊ณผ๋ฅผ ์ ๋ฌ ๋ฐ์ ์ ์์ต๋๋ค
๊ธฐ๋ฅํ๋๊ทธํค: ๊ฐ ๊ธฐ๋ฅํ๋๊ทธ๋ณ๋ก ๊ฐ๊ฒ ๋๋ ๊ณ ์ ๋ฒํธ์ ๋๋ค. ๊ธฐ๋ฅํ๋๊ทธ๋ฅผ ์์ฑํ๋ฉด ์๋์ผ๋ก ๋ฐ๊ธ๋ฉ๋๋ค.
import {HackleFeature} from "@hackler/react-sdk";
function App() {
return (
// ๊ธฐ๋ฅ ํค๊ฐ 42์ธ ๊ธฐ๋ฅ ํ๋๊ทธ์์ ์ฌ์ฉ์์ ์ํ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
// ๊ฒฐ์ ํ์ง ๋ชปํ๋ ์ํฉ์ธ ๊ฒฝ์ฐ false(๊บผ์ง ์ํ)๋ฅผ ๋ฐํํฉ๋๋ค.
<HackleFeature featureKey={42}>
{(featureOn) =>
featureOn ? (
<SuperAwesomeFeature /> // ์ผ์ง ์ํ์ผ ๋์ ๊ธฐ๋ฅ
) : (
<AwesomeFeature /> // ๊บผ์ง ์ํ์ผ ๋์ ๊ธฐ๋ฅ
)
}
</HackleFeature>
)
}import {useFeature, useLoadableFeature} from "@hackler/react-sdk";
function App() {
// ๊ธฐ๋ฅ ํค๊ฐ 42์ธ ๊ธฐ๋ฅ ํ๋๊ทธ์์ ์ฌ์ฉ์์ ์ํ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
// ๊ฒฐ์ ํ์ง ๋ชปํ๋ ์ํฉ์ธ ๊ฒฝ์ฐ false(๊บผ์ง ์ํ)๋ฅผ ๋ฐํํฉ๋๋ค.
const featureOn = useFeature(42)
return (
<>
{
featureOn ? (
<SuperAwesomeFeature /> // ์ผ์ง ์ํ์ผ ๋์ ๊ธฐ๋ฅ
) : (
<AwesomeFeature /> // ๊บผ์ง ์ํ์ผ ๋์ ๊ธฐ๋ฅ
)
}
</>
)
}
// SSR ์ฌ์ฉ ์
function App() {
// ๊ธฐ๋ฅ ํค๊ฐ 42์ธ ๊ธฐ๋ฅ ํ๋๊ทธ์์ ์ฌ์ฉ์์ ์ํ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
// ๊ฒฐ์ ํ์ง ๋ชปํ๋ ์ํฉ์ธ ๊ฒฝ์ฐ false(๊บผ์ง ์ํ)๋ฅผ ๋ฐํํฉ๋๋ค.
const { isLoading, isOn } = useLoadableFeature(42)
return (
<>
{
isOn ? (
<SuperAwesomeFeature /> // ์ผ์ง ์ํ์ผ ๋์ ๊ธฐ๋ฅ
) : (
<AwesomeFeature /> // ๊บผ์ง ์ํ์ผ ๋์ ๊ธฐ๋ฅ
)
}
</>
)
}Updated 9 days ago
