> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Niestandardowe skrypty

> Uruchamiaj własny JavaScript w Aftersell Cart za pomocą slotów skryptów Initialization i On cart update.

Niestandardowe skrypty pozwalają uruchamiać własny JavaScript na koszyku za pomocą [Cart SDK](/pl/aftersell/cart/sdk-overview). Dodaj je w edytorze koszyka w **Cart settings → Custom script**, gdzie lista rozwijana przełącza między dwoma slotami: **Initialization** i **On cart update**.

W tych edytorach pisz czysty JavaScript, bez tagów `<script>`. **On cart update** ma akcję **Reset to default**, która przywraca jego szablon startowy; **Initialization** nie ma, więc zachowaj własną kopię, zanim go wyczyścisz.

<Note>
  Wiele z tego, co sprzedawcy kiedyś skryptowali, jest teraz wbudowanym ustawieniem. Najpierw sprawdź [Zanim napiszesz skrypt](/pl/aftersell/cart/sdk-use-cases#before-you-write-a-script): ustawienie działa dalej po przeprojektowaniach koszyka, a twój skrypt może nie.
</Note>

<div id="which-slot-to-use">
  ## Którego slotu użyć
</div>

|                   | Initialization                                                                                                                                                                         | On cart update                                                                 |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| **Uruchamia się** | Raz, gdy koszyk się ładuje.                                                                                                                                                            | Przy każdej zmianie koszyka po pierwszym załadowaniu.                          |
| **Piszesz**       | Cały skrypt.                                                                                                                                                                           | Tylko treść handlera. Wrapper `cart_updated` jest zablokowany.                 |
| **Używaj do**     | Jednorazowej rejestracji zachowania: [`configure`](/pl/aftersell/cart/sdk-configure), [`events.on`](/pl/aftersell/cart/sdk-events), [`hooks.register*`](/pl/aftersell/cart/sdk-hooks). | Reguł, które muszą być ponownie oceniane względem bieżącej zawartości koszyka. |
| **Przykład**      | Ukrycie linii darmowych prezentów transformacją linii.                                                                                                                                 | Utrzymywanie darmowego prezentu w synchronizacji z progiem wydatków.           |

<div id="initialization">
  ## Initialization
</div>

Skrypt **Initialization** uruchamia się **raz, gdy koszyk się ładuje**. To twój punkt wejścia do konfiguracji: ustawiania zachowania koszyka, subskrybowania zdarzeń i rejestrowania hooków. [SDK](/pl/aftersell/cart/sdk-overview) jest dostępne jako `window.aftersell.cart`.

Wywołania konfiguracyjne, które tu wykonujesz ([`configure(...)`](/pl/aftersell/cart/sdk-configure), [`events.on(...)`](/pl/aftersell/cart/sdk-events), [`hooks.*`](/pl/aftersell/cart/sdk-hooks)), można bezpiecznie wywoływać na początku skryptu, nawet zanim koszyk w pełni się uruchomi; są buforowane i stosowane, gdy to nastąpi. Akcje, które odczytują lub zmieniają koszyk (jak [`addItem`](/pl/aftersell/cart/sdk-actions#additemvariantid-quantity) czy [`getCart`](/pl/aftersell/cart/sdk-actions#getcart)), powinny działać wewnątrz [`ready()`](/pl/aftersell/cart/sdk-overview#ready) lub handlera zdarzenia.

Slot zaczyna z trzema **zakomentowanymi** przykładami — otwieraniem szuflady przy każdym dodaniu, reagowaniem na `cart_loaded` i ukrywaniem linii darmowych prezentów — więc nietknięty skrypt Initialization nic nie robi. Odkomentuj jeden, aby go wypróbować, albo je zastąp.

Naturalny kształt tego slotu to **jednorazowa rejestracja bez udziału zdarzeń**: zarejestruj zachowanie raz i pozwól koszykowi stosować je od tej pory. Ukrywanie linii darmowych prezentów w szufladzie, bez zmiany sumy, to dostarczony przykład tego podejścia:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerLineTransform((line) => {
  if (line.finalLinePrice === 0) line.setHidden(true);
});
```

[`registerLineTransform`](/pl/aftersell/cart/sdk-hooks#registerlinetransform) uruchamia się dla każdej linii podczas jej renderowania, a `setHidden` dotyczy tylko wyświetlania, więc linia pozostaje w koszyku i nadal liczy się do sumy — po prostu nie pokazuje się w szufladzie. Zobacz [Ukrywanie i zmiana etykiet linii koszyka](/pl/aftersell/cart/sdk-use-case-hide-lines), aby poznać więcej możliwości transformacji.

Akcje odczytujące koszyk umieszczaj wewnątrz `ready()`:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.ready().then(() => {
  const state = window.aftersell.cart.actions.getCart();
  console.log('Cart loaded with', state.itemCount, 'items');
});
```

Sięganie do DOM koszyka wymaga tego samego oczekiwania oraz [`shadowRoot`](/pl/aftersell/cart/sdk-overview#shadowroot): koszyk renderuje się wewnątrz shadow rootu, więc `document.querySelector` nie widzi niczego w szufladzie.

<Tip>
  Rozgałęziasz logikę według rynku, kraju lub waluty **zanim** koszyk się załaduje? Odczytaj zamiast tego [`context`](/pl/aftersell/cart/sdk-overview#context). Jest dostępny synchronicznie, bez potrzeby `ready()`, więc możesz całkowicie pominąć rejestrowanie handlerów dla kupujących, których reguła nie dotyczy.
</Tip>

<div id="on-cart-update">
  ## On cart update
</div>

Skrypt **On cart update** uruchamia się przy każdej zmianie koszyka. To zablokowany wrapper wokół subskrypcji `cart_updated`, więc edytujesz tylko treść, a twój kod otrzymuje zaktualizowany `cart`.

Ten slot służy do reguł, które muszą być **ponownie oceniane przy każdej zmianie koszyka**. Próg darmowego prezentu to klasyczny przypadek (wydaj \$75, odbierz darmową torbę), ponieważ odpowiedź zależy od bieżącej zawartości i nic innego nie powie ci, kiedy się zmienia:

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.events.on('cart_updated', (cart) => {
  const GIFT_VARIANT_ID = 1234567890;
  const THRESHOLD = 7500;   // $75.00, in cents

  let giftLine = null;
  let subtotal = 0;
  (cart.items ?? []).forEach((line) => {
    if (line.variantId === GIFT_VARIANT_ID) giftLine = line;
    else subtotal += line.finalLinePrice;   // the gift itself never counts toward the threshold
  });

  const shouldHaveGift = subtotal >= THRESHOLD;
  const hasGift = Boolean(giftLine);

  // Bail when the cart already matches. This is the part that matters: adding or
  // removing an item fires cart_updated again, so without this check the handler
  // re-enters itself forever.
  if (shouldHaveGift === hasGift) return;

  if (shouldHaveGift) window.aftersell.cart.actions.addItem(GIFT_VARIANT_ID, 1);
  else window.aftersell.cart.actions.removeItem(giftLine.key);
});
```

<div id="keeping-the-cart-in-a-desired-state">
  ### Utrzymywanie koszyka w pożądanym stanie
</div>

Linia `if (shouldHaveGift === hasGift) return;` czyni ten skrypt bezpiecznym i uogólnia się na każdy skrypt utrzymujący koszyk w pożądanym stanie. Ten slot zarówno reaguje na zmiany koszyka, jak i je powoduje, więc każde `addItem` lub `removeItem` ponownie do niego wchodzi. Opisz stan, którego chcesz, porównaj go ze stanem, który masz, i wyjdź wcześnie, gdy już się zgadzają — dzięki temu handler zbiega się po jednym przebiegu zamiast zapętlać. Zobacz [dwie zasady](/pl/aftersell/cart/sdk-events#the-two-rules), aby poznać wersję bez zabezpieczenia, której należy unikać, oraz dlaczego payload jest tylko do odczytu.

W wolniejszym sklepie warto też trzymać flagę „w toku” na poziomie modułu, aby dwie szybkie zmiany nie mogły obie rozpocząć dodawania, zanim pierwsze się zakończy.

<Note>
  `cart_updated` odpala się tylko przy zmianach **po** pierwszym załadowaniu ([czasowanie zdarzeń](/pl/aftersell/cart/sdk-events#cart_updated)), więc skrypt w tym slocie nie uzgodni koszyka, który już kwalifikuje się w momencie załadowania strony. Aby obsłużyć oba przypadki, zasubskrybuj `cart_loaded` i `cart_updated` tą samą funkcją ze slotu **Initialization**. Zobacz [Automatyczne dodawanie darmowego prezentu przy progu](/pl/aftersell/cart/sdk-use-case-free-gift).
</Note>

<div id="when-a-script-breaks">
  ## Gdy skrypt się psuje
</div>

Każdy slot działa we własnej piaskownicy, więc zepsuty skrypt **Initialization** nie może zatrzymać działania **On cart update**, a żaden z nich nie może zepsuć samego koszyka.

W obrębie slotu jednak wykonanie **zatrzymuje się na pierwszym błędzie**. Wszystko poniżej tej linii jest pomijane, co oznacza, że żadne `configure`, `events.on` czy `hooks.register*` dalej w kodzie nigdy nie zostanie zarejestrowane. To typowe wyjaśnienie sytuacji „mój handler nigdy się nie odpala”, gdy kod wygląda poprawnie.

Koszyk wskazuje błędną linię w konsoli przeglądarki, a każdy slot działa pod własną nazwą pliku (`aftersell-cart-init.js` i `aftersell-cart-cart-update.js`), więc możesz otworzyć dowolny z nich w panelu Sources w DevTools i ustawić breakpointy. Zobacz [Debugowanie](/pl/aftersell/cart/sdk-overview#debugging), aby poznać dokładne komunikaty oraz kanał debugowania, który wychwytuje błędy hooków nietrafiające do konsoli.

Ponieważ `cart_loaded` [odtwarza się dla spóźnionych subskrybentów](/pl/aftersell/cart/sdk-events#cart_loaded), kolejność rejestracji nigdy nie ma znaczenia. Najbezpieczniejsza struktura to zarejestrować wszystko najpierw i wykonywać ryzykowną pracę wewnątrz handlerów, gdzie wyjątek jest izolowany do tego handlera.

<div id="where-to-go-next">
  ## Co dalej
</div>

* **[Cart SDK](/pl/aftersell/cart/sdk-overview)**: niestandardowe skrypty to sposób uruchamiania kodu SDK. Zobacz referencje [configure](/pl/aftersell/cart/sdk-configure), [events](/pl/aftersell/cart/sdk-events), [actions](/pl/aftersell/cart/sdk-actions) i [hooks](/pl/aftersell/cart/sdk-hooks), aby poznać pełną powierzchnię, [obiekt koszyka](/pl/aftersell/cart/sdk-cart-object) dla kształtu danych otrzymywanych przez handlery oraz [przypadki użycia](/pl/aftersell/cart/sdk-use-cases) z gotowymi fragmentami kodu.
* **[Bloki Custom code](/pl/aftersell/cart/custom-code-blocks)**: do dodawania struktury do koszyka. Pamiętaj, że tryb HTML bloku Custom code **nie** uruchamia JavaScriptu; do logiki używaj niestandardowych skryptów (lub trybu React tego bloku).
