Skip to main content

Overview

The BLACKICE Portal search interface is a Vue.js-based component that provides multi-engine search capabilities. Users can select from various search engines and execute queries directly from the portal interface.

Vue Component Architecture

The search component uses Vue 3’s Composition API with reactive state management:
Home.html:33-50
import { ref, computed, onMounted } from 'vue';

const searchQuery = ref('');
const selectedEngineIndex = ref(0);

// Search engines configuration
const engines = [
  {
    name: 'Brave',
    value: 'brave',
    url: 'https://search.brave.com/search?q='
  },
  {
    name: 'Google',
    value: 'google',
    url: 'https://www.google.com/search?q='
  },
  {
    name: 'DuckDuckGo',
    value: 'duckduckgo',
    url: 'https://duckduckgo.com/?q='
  },
  {
    name: 'Bing',
    value: 'bing',
    url: 'https://www.bing.com/search?q='
  },
  {
    name: 'Perplexity',
    value: 'perplexity',
    url: 'https://www.perplexity.ai/search?q='
  },
  {
    name: 'You.com',
    value: 'you',
    url: 'https://you.com/search?q='
  }
];

const currentEngine = computed(() => engines[selectedEngineIndex.value]);
The search component is embedded as a base64-encoded Vue SFC in the HTML file and uses ES module imports from CDN.

Search Engines Configuration

The portal supports multiple search engines with unified interface:
Default Search Engine
{
  name: 'Brave',
  value: 'brave',
  url: 'https://search.brave.com/search?q='
}
Privacy-focused search engine with independent index.

Search Interface Components

Engine Selector

The engine selector dropdown uses Vue’s v-model for two-way binding:
<select
  class="engine-selector"
  v-model="selectedEngineIndex"
  title="Select Search Engine"
>
  <option
    v-for="(engine, index) in engines"
    :key="engine.value"
    :value="index"
  >
    <span class="engine-name">{{ engine.name }}</span>
  </option>
</select>

Search Input

The search input uses v-model with keyboard event handling:
<input
  type="text"
  v-model.trim="searchQuery"
  @keyup.enter="handleSearch"
  class="search-input"
  placeholder="Search the web..."
  autofocus
/>
The .trim modifier automatically removes whitespace from user input.

Search Actions

The search button triggers the handleSearch method:
<div class="search-actions">
  <button @click="handleSearch" class="search-btn">
    Search
  </button>
  <button @click="openDevMode" class="dev-btn">
    Dev Mode
  </button>
</div>

Search Functionality

Handle Search Method

The search handler constructs URLs with encoded queries:
const handleSearch = () => {
  if (!searchQuery.value) return;
  
  const query = encodeURIComponent(searchQuery.value);
  const searchUrl = currentEngine.value.url + query;
  
  window.open(searchUrl, '_blank');
};

Computed Properties

The current engine is computed reactively:
const currentEngine = computed(() => {
  return engines[selectedEngineIndex.value];
});
Computed properties automatically update when dependencies change, ensuring the UI reflects the selected engine.

Styling & Layout

The search interface features glassmorphism effects:
.search-wrapper {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 20px;
  padding: 32px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}

.engine-selector {
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: white;
  padding: 12px 16px;
  border-radius: 12px;
  font-weight: 600;
}

.search-input {
  background: transparent;
  border: 2px solid rgba(255, 255, 255, 0.3);
  color: white;
  padding: 16px 20px;
  font-size: 18px;
  border-radius: 12px;
  width: 100%;
}

.search-input::placeholder {
  color: rgba(255, 255, 255, 0.6);
}

Component Integration

The search component integrates with the portal using Vue 3’s module system:
<script type="importmap">
{
  "imports": {
    "vue": "https://cdn.jsdelivr.net/npm/vue@3/dist/vue.runtime.esm-browser.prod.js",
    "./script": "data:text/javascript;charset=UTF-8;base64,...",
    "./Component.vue": "data:text/javascript;charset=UTF-8;base64,..."
  }
}
</script>
<script type="module">
import { createApp } from 'vue';
import Component from './Component.vue';

createApp(Component)
  .mount('#livecodes-app');
</script>

Adding New Search Engines

To add a new search engine, extend the engines array:
const engines = [
  // ... existing engines
  {
    name: 'Custom Engine',
    value: 'custom',
    url: 'https://example.com/search?query='
  }
];
Requirements for new engines:
  • Unique value identifier
  • User-friendly name
  • Valid url with query parameter placeholder
  • URL should end with the query parameter separator (e.g., ?q= or ?query=)

Reactive State Flow

Keyboard Shortcuts

  • Enter: Execute search with current query
  • Tab: Navigate between engine selector and search input
  • Escape: Clear search query (if implemented)
The search input includes autofocus attribute for immediate keyboard access on page load.

Build docs developers (and LLMs) love