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:
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:
Brave
Google
DuckDuckGo
Bing
Perplexity
You.com
Default Search Engine {
name : 'Brave' ,
value : 'brave' ,
url : 'https://search.brave.com/search?q='
}
Privacy-focused search engine with independent index. {
name : 'Google' ,
value : 'google' ,
url : 'https://www.google.com/search?q='
}
Traditional search with comprehensive results. {
name : 'DuckDuckGo' ,
value : 'duckduckgo' ,
url : 'https://duckduckgo.com/?q='
}
Privacy-first search without tracking. {
name : 'Bing' ,
value : 'bing' ,
url : 'https://www.bing.com/search?q='
}
Microsoft’s search engine with AI integration. {
name : 'Perplexity' ,
value : 'perplexity' ,
url : 'https://www.perplexity.ai/search?q='
}
AI-powered search with conversational answers. {
name : 'You.com' ,
value : 'you' ,
url : 'https://you.com/search?q='
}
Personalized search with AI assistance.
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 ( 10 px );
border-radius : 20 px ;
padding : 32 px ;
box-shadow : 0 8 px 32 px rgba ( 0 , 0 , 0 , 0.1 );
}
.engine-selector {
background : rgba ( 0 , 0 , 0 , 0.2 );
border : 1 px solid rgba ( 255 , 255 , 255 , 0.2 );
color : white ;
padding : 12 px 16 px ;
border-radius : 12 px ;
font-weight : 600 ;
}
.search-input {
background : transparent ;
border : 2 px solid rgba ( 255 , 255 , 255 , 0.3 );
color : white ;
padding : 16 px 20 px ;
font-size : 18 px ;
border-radius : 12 px ;
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 >
App Mount
Template Structure
< 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.