# How to Mark a Word as Wrong and Retrieve the Wrong Words List in TypeWords

> Learn how to mark words as wrong in TypeWords and access the wrong words list from global or session data. Improve your typing accuracy effectively.

- Repository: [Zyronon/TypeWords](https://github.com/zyronon/TypeWords)
- Tags: how-to-guide
- Published: 2026-09-03

---

**In TypeWords, a word is marked as wrong during a practice session when the user's input doesn't match the expected word, and the wrong words list can be retrieved from either `store.wrong.words` (global store) or `data.wrongWords` (session data).**

TypeWords is an open-source typing practice application that tracks your mistakes to help you improve. Understanding how the application records and manages wrong words is essential for customizing practice sessions, building statistics dashboards, or implementing retry flows. This guide explains the complete wrong-word lifecycle based on the TypeWords source code.

## How Words Are Marked as Wrong

The wrong-word detection logic lives in [`app/core/composables/practice-words/usePracticeWordSession.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/composables/practice-words/usePracticeWordSession.ts). When a typing mismatch occurs, the system executes a three-step process:

1. **Increment session counter** — `data.wrongTimes` tracks mistakes in the current practice run
2. **Add to global store** — `store.wrong.words` maintains the canonical list of all wrong words
3. **Add to session list** — `data.wrongWords` powers the retry-specific flow

Here's the core implementation from lines 167-188:

```typescript
// Inside usePracticeWordSession.ts – wrong-word detection
if (isWrong) {
  // 1. Increment per-session wrong counter
  data.wrongTimes++

  // 2. Add to global wrong-word store (deduplicated)
  const storedWrongIndex = store.wrong.words.findIndex(item => item.word === word.word)
  if (storedWrongIndex < 0) {
    store.wrong.words.push(word)
    store.wrong.length = store.wrong.words.length
  }

  // 3. Add to session-level wrong-words list (for retry flow)
  if (!data.wrongWords.some(item => item.word === word.word)) {
    data.wrongWords.push(word)
  }
}

```

The **global store** (`store.wrong.words`) persists across the entire application session and provides the `length` property for quick statistics display. The **session data** (`data.wrongWords`) is scoped to the current practice flow and drives the "Wrong Words Retry" feature.

## Where Wrong Words Are Stored

TypeWords maintains wrong words in two complementary locations:

| Location | File | Purpose |
|----------|------|---------|
| `store.wrong.words` | [`app/core/stores/base.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/base.ts) (line 112) | Global collection for statistics and persistence |
| `data.wrongWords` | [`app/core/composables/practice-words/usePracticeWordSession.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/composables/practice-words/usePracticeWordSession.ts) (lines 175-188) | Session-specific list for retry workflows |

### Global Store Structure

The base store in [`app/core/stores/base.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/base.ts) defines the wrong-words structure:

```typescript
// From app/core/stores/base.ts
interface WrongState {
  words: Word[]      // All wrong words in current session
  length: number     // Cached length for UI performance
}

```

The `length` property stays synchronized whenever words are added or removed, avoiding expensive array length calculations in reactive components.

### Session Data Interface

The `PracticeData` type in [`app/core/types/types.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/types/types.ts) declares the session-level list:

```typescript
// From app/core/types/types.ts
interface PracticeData {
  wrongWords: Word[]      // Wrong words for current retry cycle
  wrongTimes: number      // Total mistake count this session
  // ... other practice fields
}

```

## Retrieving the Wrong Words List

### Method 1: Access Global Store Directly

For statistics panels, progress tracking, or cross-session analysis:

```typescript
import { useBaseStore } from '@/core/stores/base'

const store = useBaseStore()

// Get all wrong words
const allWrongWords = store.wrong.words

// Get count (cached for performance)
const wrongCount = store.wrong.length

// Map to displayable strings
const wrongWordStrings = allWrongWords.map(w => w.word)

```

**Source:** [`app/core/stores/base.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/base.ts) — the store exposes `wrong.words` and `wrong.length` as reactive state.

### Method 2: Access via Practice Navigator

For retry flows and practice-specific logic, use `usePracticeWordNavigator`:

```typescript
import { usePracticeWordNavigator } from '@/core/composables/practice-words/usePracticeWordNavigator'

const navigator = usePracticeWordNavigator()

// Retrieve words specifically for retry
const wrongWordsForRetry = navigator.getSource('wrongWords')

```

The navigator's `getSource` method (line 54 in [`usePracticeWordNavigator.ts`](https://github.com/zyronon/TypeWords/blob/main/usePracticeWordNavigator.ts)) returns `data.wrongWords` when the source parameter is `'wrongWords'`:

```typescript
// From usePracticeWordNavigator.ts — line 54
case 'wrongWords':
  return data.wrongWords

```

This abstraction allows the UI to switch between word sources (regular practice, wrong-word retry, favorites, etc.) without knowing implementation details.

## Clearing and Managing Wrong Words

When users complete a retry cycle or manually clear their mistakes, TypeWords filters the list using `checkWordIsNeedNext`:

```typescript
// From usePracticeWordNavigator.ts — lines 337-340
data.wrongWords = data.wrongWords.filter(v => !deps.checkWordIsNeedNext(v))

if (data.wrongWords.length > 0) {
  // Continue retrying remaining words
}

```

This cleanup happens in the `wrongWordClear` action handler. Words that pass the check (no longer need practice) are removed from both the session list and, indirectly, from the global store through reactive synchronization.

## Persisting Wrong Words

The cache utility in [`app/core/utils/cache.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/utils/cache.ts) handles serialization of practice data, including `wrongWordsStr` — a stringified version of the wrong words array for localStorage persistence. This enables wrong-word tracking to survive page refreshes during a single browser session.

## Summary

- **Marking wrong**: [`usePracticeWordSession.ts`](https://github.com/zyronon/TypeWords/blob/main/usePracticeWordSession.ts) detects mismatches and populates both `store.wrong.words` (global) and `data.wrongWords` (session)
- **Global access**: Use `useBaseStore().wrong.words` from [`app/core/stores/base.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/stores/base.ts)
- **Session access**: Use `usePracticeWordNavigator().getSource('wrongWords')` from [`app/core/composables/practice-words/usePracticeWordNavigator.ts`](https://github.com/zyronon/TypeWords/blob/main/app/core/composables/practice-words/usePracticeWordNavigator.ts)
- **Deduplication**: Both lists prevent duplicate entries via `findIndex` and `some` checks
- **Cleanup**: The `wrongWordClear` action filters completed words from `data.wrongWords`

## Frequently Asked Questions

### How does TypeWords prevent the same word from being added twice to the wrong words list?

Both storage locations check for existing entries before pushing. The global store uses `findIndex` on `store.wrong.words`, while the session list uses `some` on `data.wrongWords`. These checks run on every wrong-word detection event in [`usePracticeWordSession.ts`](https://github.com/zyronon/TypeWords/blob/main/usePracticeWordSession.ts) (lines 172-176 and 177-180).

### What's the difference between `store.wrong.words` and `data.wrongWords`?

`store.wrong.words` lives in the global Pinia store and persists for the entire application lifecycle — it powers statistics and cross-session tracking. `data.wrongWords` is local to the current practice session composable and specifically drives the wrong-word retry workflow. The session list can be filtered and cleared independently without affecting historical statistics.

### Can I access wrong words from outside the practice composables?

Yes. Import `useBaseStore` from `@/core/stores/base` anywhere in the application to access `store.wrong.words`. This store is framework-agnostic and doesn't require being inside a practice session context, making it suitable for dashboard components, statistics widgets, or export features.

### When are wrong words removed from the lists?

Words are filtered from `data.wrongWords` during the `wrongWordClear` action in [`usePracticeWordNavigator.ts`](https://github.com/zyronon/TypeWords/blob/main/usePracticeWordNavigator.ts) (lines 337-340) when they no longer need practice — typically after successful completion or manual dismissal. The global `store.wrong.words` maintains a broader historical record that may persist longer depending on the application's session management.