Implementing Search History Persistence with Vue and LocalStorage

When building search functionality in a Vue application, implementing persistant search history improves user experience by allowing users to quickly access their recent queries across sessions.

Core Implementation Strategy

The approach involves three key principles:

  1. Store search history data in browser localStorage for permanent persistence
  2. Load cached data into component state during initialization
  3. Synchronize all modifications (additions and deletions) to the localStorage cache

Cmoponent Template

<template>
  <div class="search-container">
    <div v-if="displayHistory" class="history-panel">
      <div class="header-row">
        <h4>Recent Searches</h4>
        <button @click="removeAllHistory" class="delete-btn">
          <img src="/assets/trash-icon.png" alt="Clear" width="16"/>
        </button>
      </div>
      <div class="history-items">
        <span 
          v-for="(keyword, idx) in recentSearches" 
          :key="idx"
          @click="executeSearch(keyword)"
          class="keyword-tag">
          {{ keyword }}
        </span>
      </div>
    </div>
  </div>
</template>

Component State Definition

<script>
export default {
  name: 'SearchHistory',
  
  data() {
    return {
      recentSearches: [],
      displayHistory: false,
      isLoading: false
    }
  },
  
  mounted() {
    this.loadPersistedHistory()
  },
  
  methods: {
    // Restore search history from localStorage
    loadPersistedHistory() {
      const cached = localStorage.getItem('userSearchQueries')
      if (cached) {
        try {
          this.recentSearches = JSON.parse(cached)
          this.displayHistory = this.recentSearches.length > 0
        } catch (e) {
          this.recentSearches = []
        }
      }
    },
    
    // Persist current history to localStorage
    persistHistory() {
      localStorage.setItem('userSearchQueries', JSON.stringify(this.recentSearches))
    },
    
    // Clear all search history
    removeAllHistory() {
      localStorage.removeItem('userSearchQueries')
      this.recentSearches = []
      this.displayHistory = false
    },
    
    // Add new search term to history
    addSearchTerm(term) {
      // Skip empty searches
      if (!term || !term.trim()) return
      
      const trimmedTerm = term.trim()
      
      // Remove existing duplicate if present
      const existingIndex = this.recentSearches.indexOf(trimmedTerm)
      if (existingIndex !== -1) {
        this.recentSearches.splice(existingIndex, 1)
      }
      
      // Insert at beginning
      this.recentSearches.unshift(trimmedTerm)
      
      // Maintain maximum of 10 items
      if (this.recentSearches.length > 10) {
        this.recentSearches.pop()
      }
      
      this.persistHistory()
    },
    
    // Execute search using historical keyword
    executeSearch(keyword) {
      this.performSearch(keyword).then(results => {
        this.searchResults = results
        this.displayHistory = false
      })
    },
    
    async performSearch(query) {
      this.isLoading = true
      try {
        const response = await searchApi.fetchResults(query)
        return response.data.items
      } finally {
        this.isLoading = false
      }
    }
  }
}
</script>

Integration Example

To use this component with your search form, invoke the addSearchTerm method when a search is submitted:

// In your search form component
handleSearchSubmit(query) {
  // Add to history before executing search
  this.$refs.historyComponent.addSearchTerm(query)
  
  // Proceed with search execution
  this.performSearch(query)
}

Key Features

  • Duplicate Prevention: If a search term already exists in history, it moves to the top instead of creating duplicates
  • Storage Limit: History is capped at 10 items to prevent unbounded localStorage growth
  • Empty Value Handling: Whitespace-only inputs are filtered out
  • Error Resilience: JSON parsing failures during restore are handled gracefully

This implementation provides a seamless experience where users can quickly retry previous searches while maintaining privacy through browser-based storage that persists until explicitly cleared.

Tags: vuejs javascript localstorage Caching web-development

Posted on Thu, 27 Aug 2026 16:57:12 +0000 by demonicfoetus