> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-sync-clickhouse-operator-docs-7e82242.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstarts explorer

> Explore quickstart guides to get up and running with ClickHouse

export const QuickStartsGrid = ({quickStartsData, featuredIds = []}) => {
  const [searchTerm, setSearchTerm] = useState(() => {
    if (typeof window !== 'undefined') {
      return localStorage.getItem('quickstarts-search') || '';
    }
    return '';
  });
  const [selectedUseCases, setSelectedUseCases] = useState(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('quickstarts-usecases');
      return saved ? JSON.parse(saved) : ['All'];
    }
    return ['All'];
  });
  const [selectedProducts, setSelectedProducts] = useState(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('quickstarts-products');
      return saved ? JSON.parse(saved) : ['All'];
    }
    return ['All'];
  });
  const [selectedLevels, setSelectedLevels] = useState(() => {
    if (typeof window !== 'undefined') {
      const saved = localStorage.getItem('quickstarts-levels');
      return saved ? JSON.parse(saved) : ['All'];
    }
    return ['All'];
  });
  const [currentPage, setCurrentPage] = useState(1);
  const itemsPerPage = 6;
  const [useCasesDropdownOpen, setUseCasesDropdownOpen] = useState(true);
  const [productsDropdownOpen, setProductsDropdownOpen] = useState(true);
  const [levelsDropdownOpen, setLevelsDropdownOpen] = useState(true);
  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('quickstarts-search', searchTerm);
    }
  }, [searchTerm]);
  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('quickstarts-usecases', JSON.stringify(selectedUseCases));
    }
  }, [selectedUseCases]);
  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('quickstarts-products', JSON.stringify(selectedProducts));
    }
  }, [selectedProducts]);
  useEffect(() => {
    if (typeof window !== 'undefined') {
      localStorage.setItem('quickstarts-levels', JSON.stringify(selectedLevels));
    }
  }, [selectedLevels]);
  const useCaseOptions = ['All', 'Real-time analytics', 'Data warehousing', 'Observability', 'AI/ML'];
  const productOptions = ['All', 'Self-managed', 'Cloud', 'ClickPipes', 'Language clients', 'ClickStack', 'chDB'];
  const levelOptions = ['All', 'Beginner', 'Intermediate', 'Advanced'];
  const toggleUseCase = useCase => {
    setSelectedUseCases(prev => {
      if (useCase === 'All') {
        return ['All'];
      } else {
        const withoutAll = prev.filter(uc => uc !== 'All');
        const result = withoutAll.includes(useCase) ? withoutAll.filter(uc => uc !== useCase) : [...withoutAll, useCase];
        return result.length === 0 ? ['All'] : result;
      }
    });
  };
  const toggleProduct = product => {
    setSelectedProducts(prev => {
      if (product === 'All') {
        return ['All'];
      } else {
        const withoutAll = prev.filter(p => p !== 'All');
        const result = withoutAll.includes(product) ? withoutAll.filter(p => p !== product) : [...withoutAll, product];
        return result.length === 0 ? ['All'] : result;
      }
    });
  };
  const toggleLevel = level => {
    setSelectedLevels(prev => {
      if (level === 'All') {
        return ['All'];
      } else {
        const withoutAll = prev.filter(l => l !== 'All');
        const result = withoutAll.includes(level) ? withoutAll.filter(l => l !== level) : [...withoutAll, level];
        return result.length === 0 ? ['All'] : result;
      }
    });
  };
  useEffect(() => {
    setCurrentPage(1);
  }, [searchTerm, selectedUseCases, selectedProducts, selectedLevels]);
  const resetFilters = () => {
    setSearchTerm('');
    setSelectedUseCases(['All']);
    setSelectedProducts(['All']);
    setSelectedLevels(['All']);
  };
  const hasActiveFilters = searchTerm !== '' || selectedUseCases.length > 0 && !selectedUseCases.includes('All') || selectedProducts.length > 0 && !selectedProducts.includes('All') || selectedLevels.length > 0 && !selectedLevels.includes('All');
  const filteredQuickStarts = useMemo(() => {
    return quickStartsData.filter(quickStart => {
      if (featuredIds.includes(quickStart.id)) return false;
      const matchesSearch = searchTerm === '' || quickStart.title.toLowerCase().includes(searchTerm.toLowerCase()) || quickStart.description.toLowerCase().includes(searchTerm.toLowerCase());
      const matchesUseCases = selectedUseCases.length === 0 || selectedUseCases.includes('All') || quickStart.useCases.includes('All') || selectedUseCases.some(uc => quickStart.useCases.includes(uc));
      const matchesProducts = selectedProducts.length === 0 || selectedProducts.includes('All') || selectedProducts.some(p => quickStart.products.includes(p));
      const matchesLevel = selectedLevels.length === 0 || selectedLevels.includes('All') || quickStart.level && selectedLevels.includes(quickStart.level);
      return matchesSearch && matchesUseCases && matchesProducts && matchesLevel;
    });
  }, [quickStartsData, searchTerm, selectedUseCases, selectedProducts, selectedLevels, featuredIds]);
  const Expandable = ({label, options, selectedOptions, onToggle, isOpen, setIsOpen}) => {
    const activeCount = selectedOptions.filter(o => o !== 'All').length;
    const displayLabel = activeCount > 0 ? `${label} (${activeCount})` : label;
    return <div style={{
      minWidth: '160px'
    }}>
        <button onClick={() => setIsOpen(!isOpen)} className="text-sm font-medium transition-all cursor-pointer flex items-center justify-between w-full text-black dark:text-white" style={{
      padding: '4px 0',
      gap: '8px'
    }}>
          <span className="font-semibold">{displayLabel}</span>
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" className={`transition-transform duration-200 ${isOpen ? 'rotate-180' : 'rotate-0'}`}>
            <path d="M2.5 4.5L6 8L9.5 4.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </button>
        {isOpen && <div className="mt-1">
            {options.map(option => <label key={option} className="flex items-center gap-2 py-1.5 cursor-pointer transition-colors" onClick={e => {
      e.preventDefault();
      onToggle(option);
    }}>
                <span className="flex items-center justify-center w-4 h-4 rounded border flex-shrink-0" style={{
      borderColor: selectedOptions.includes(option) ? '#FAFF69' : 'rgba(156, 163, 175, 0.6)',
      backgroundColor: selectedOptions.includes(option) ? '#FAFF69' : 'transparent'
    }}>
                  {selectedOptions.includes(option) && <svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
                      <path d="M2 5L4 7L8 3" stroke="black" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                    </svg>}
                </span>
                <span className="text-sm text-black dark:text-white">
                  {option}
                </span>
              </label>)}
          </div>}
      </div>;
  };
  const featuredQuickStarts = quickStartsData.filter(qs => featuredIds.includes(qs.id));
  return <>
      <div style={{
    maxWidth: '1312px',
    marginLeft: 'max(0px, calc((100vw - 1312px) / 2 - 19rem))',
    marginRight: 'auto',
    paddingLeft: '1.75rem',
    paddingRight: '1.75rem'
  }}>
        <div className="my-8">
          {}
          {featuredQuickStarts.length > 0 && <div className="mb-8">
              <h2 className="text-2xl font-semibold text-gray-900 dark:text-zinc-50 mb-6">Featured quickstarts</h2>
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
                {featuredQuickStarts.map(quickStart => <Card key={quickStart.id} title={quickStart.title} icon={quickStart.icon} href={quickStart.href}>
                    <span className="block mt-6">{quickStart.description}</span>
                  </Card>)}
              </div>
            </div>}

          {}
          <div className="flex flex-col lg:flex-row gap-8">
            {}
            <div className="lg:w-64 flex-shrink-0">
              <div className="lg:sticky space-y-6" style={{
    top: '8.5rem'
  }}>
                {}
                <div>
                  <label className="block text-sm font-semibold text-gray-900 dark:text-zinc-50 mb-3">
                    Search
                  </label>
                  <div className="relative w-full">
                    <svg className="absolute pointer-events-none z-10" style={{
    left: '12px',
    top: '50%',
    transform: 'translateY(-50%)',
    width: '16px',
    height: '16px',
    color: '#666'
  }} fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
                    </svg>
                    <input type="text" placeholder="Search quickstarts..." value={searchTerm} onChange={e => setSearchTerm(e.target.value)} className="w-full text-sm border rounded-xl focus:outline-none bg-white dark:bg-[#1B1B18] text-black dark:text-white border-gray-300 dark:border-gray-600 focus:border-black dark:focus:border-[#FAFF69]" style={{
    height: '42px',
    padding: '0.5rem 0.75rem 0.5rem 2.75rem',
    lineHeight: '1.4',
    boxSizing: 'border-box'
  }} />
                  </div>
                </div>

                {}
                <div>
                  <div className="space-y-3">
                    <Expandable label="Use cases" options={useCaseOptions} selectedOptions={selectedUseCases} onToggle={toggleUseCase} isOpen={useCasesDropdownOpen} setIsOpen={setUseCasesDropdownOpen} />
                    <Expandable label="Features" options={productOptions} selectedOptions={selectedProducts} onToggle={toggleProduct} isOpen={productsDropdownOpen} setIsOpen={setProductsDropdownOpen} />
                    <Expandable label="Level" options={levelOptions} selectedOptions={selectedLevels} onToggle={toggleLevel} isOpen={levelsDropdownOpen} setIsOpen={setLevelsDropdownOpen} />
                  </div>
                </div>

                {}
                {hasActiveFilters && <button onClick={resetFilters} className="w-full text-sm font-medium px-4 py-2 rounded-lg transition-all cursor-pointer border border-gray-300 dark:border-white/20 hover:border-black dark:hover:border-[#FAFF69] bg-white dark:bg-[#1B1B18] text-black dark:text-white">
                    Reset filters
                  </button>}
              </div>
            </div>

            {}
            <div className="flex-1">
              <h2 className="text-2xl font-semibold text-gray-900 dark:text-zinc-50 mb-6">Explore quickstarts</h2>
              {filteredQuickStarts.length > 0 ? <>
                  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                    {filteredQuickStarts.slice((currentPage - 1) * itemsPerPage, currentPage * itemsPerPage).map(quickStart => <Card key={quickStart.id} title={quickStart.title} icon={quickStart.icon} href={quickStart.href}>
                          <span className="block mt-6">{quickStart.description}</span>
                        </Card>)}
                  </div>
                  {}
                  {(() => {
    const totalPages = Math.ceil(filteredQuickStarts.length / itemsPerPage);
    if (totalPages <= 1) return null;
    const hasPrev = currentPage > 1;
    const hasNext = currentPage < totalPages;
    return <div className="flex items-center justify-center gap-3 mt-8">
                        <button onClick={() => hasPrev && setCurrentPage(prev => prev - 1)} disabled={!hasPrev} className={`p-2 rounded-lg border transition-all ${hasPrev ? 'border-gray-300 dark:border-white/20 bg-white dark:bg-[#1B1B18] text-black dark:text-white hover:border-[#FAFF69] cursor-pointer' : 'border-gray-200 dark:border-white/10 bg-gray-50 dark:bg-[#1B1B18]/50 text-gray-300 dark:text-white/20 cursor-not-allowed'}`} aria-label="Previous page">
                          <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path d="M10 12L6 8L10 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                          </svg>
                        </button>
                        <span className="text-sm text-gray-600 dark:text-gray-400">
                          Page {currentPage} / {totalPages}
                        </span>
                        <button onClick={() => hasNext && setCurrentPage(prev => prev + 1)} disabled={!hasNext} className={`p-2 rounded-lg border transition-all ${hasNext ? 'border-gray-300 dark:border-white/20 bg-white dark:bg-[#1B1B18] text-black dark:text-white hover:border-[#FAFF69] cursor-pointer' : 'border-gray-200 dark:border-white/10 bg-gray-50 dark:bg-[#1B1B18]/50 text-gray-300 dark:text-white/20 cursor-not-allowed'}`} aria-label="Next page">
                          <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                            <path d="M6 4L10 8L6 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
                          </svg>
                        </button>
                      </div>;
  })()}
                </> : <div className="text-center py-12 flex flex-col items-center">
                  <p className="text-gray-600 dark:text-gray-400 text-lg block">
                    No quickstarts found matching your criteria.
                  </p>
                  <p className="text-gray-500 dark:text-gray-500 text-sm mt-2 block">
                    Try adjusting your filters or search term.
                  </p>
                </div>}
            </div>
          </div>
        </div>
      </div>
    </>;
};

export const featuredQuickStartIds = ['get-started-real-time-analytics', 'get-started-observability', 'get-started-data-warehousing', 'get-started-machine-learning-and-genai'];

export const quickStartsData = [{
  id: 'build-etl-pipeline-using-clickhouse',
  title: 'Build an ETL pipeline using ClickHouse',
  description: 'Learn how to ingest data from CSV and parquet files into ClickHouse Cloud',
  href: '/core/get-started/quickstarts/build-etl-pipeline-using-clickhouse',
  useCases: ['Data warehousing'],
  products: ['Cloud'],
  level: 'Beginner'
}, {
  id: 'connect-your-iceberg-catalog',
  title: 'How to connect your Iceberg catalog in ClickHouse Cloud',
  description: 'Learn how to connect ClickHouse Cloud to connect to your Data Catalog and query Iceberg tables.',
  href: '/core/get-started/quickstarts/connect-your-iceberg-catalog',
  useCases: ['Data warehousing'],
  products: ['Cloud'],
  level: 'Beginner'
}, {
  id: 'create-your-first-materialized-view',
  title: 'Create your first materialized view',
  description: 'Learn how to use materialized views in ClickHouse to pre-compute and store query results with a different sort order, enabling fast lookups on columns not covered by your primary key.',
  href: '/core/get-started/quickstarts/create-your-first-materialized-view',
  useCases: ['All'],
  products: ['Cloud', 'OSS'],
  level: 'Beginner'
}, {
  id: 'create-your-first-mergetree-table',
  title: 'Create your first MergeTree table',
  description: 'Learn how ClickHouses primary table engine works by creating a MergeTree table, loading UK property price data, and observing how parts and merges affect storage and query performance.',
  href: '/core/get-started/quickstarts/create-your-first-mergetree-table',
  useCases: ['All'],
  products: ['Cloud', 'OSS'],
  level: 'Beginner'
}, {
  id: 'create-your-first-projection',
  title: 'Create your first projection',
  description: 'Learn how to use projections in ClickHouse to store an additional sorted copy of your data within the same table, enabling fast lookups on columns not covered by your primary key.',
  href: '/core/get-started/quickstarts/create-your-first-projection',
  useCases: ['All'],
  products: ['Cloud', 'OSS'],
  level: 'Beginner'
}, {
  id: 'creating-tables',
  title: 'Creating tables in ClickHouse',
  description: 'Learn the basics of creating databases and tables in ClickHouse, including the MergeTree engine and primary keys.',
  href: '/core/get-started/quickstarts/creating-tables',
  useCases: ['All'],
  products: ['Cloud', 'OSS'],
  level: 'Beginner'
}, {
  id: 'create-your-first-service-on-cloud',
  title: 'Create your first Cloud service and load example data',
  description: 'Create a ClickHouse Cloud service, explore the SQL console, and load an example dataset to start querying real data in minutes.',
  href: '/core/get-started/quickstarts/create-your-first-service-on-cloud',
  useCases: ['All'],
  products: ['Cloud'],
  level: 'Beginner'
}, {
  id: 'insert-data-using-clickhouse-client',
  title: 'Insert data into ClickHouse Cloud using clickhouse-client',
  description: 'Learn how to use clickhouse-client to insert data from local CSV and Parquet files into a ClickHouse Cloud service from the command line.',
  href: '/core/get-started/quickstarts/insert-data-using-clickhouse-client',
  useCases: ['All'],
  products: ['Cloud'],
  level: 'Beginner'
}, {
  id: 'mutations',
  title: 'Updating and deleting ClickHouse data',
  description: 'Learn how to perform UPDATE and DELETE operations in ClickHouse using mutations and lightweight deletes.',
  href: '/core/get-started/quickstarts/mutations',
  useCases: ['All'],
  products: ['Cloud', 'OSS'],
  level: 'Beginner'
}, {
  id: 'obtain-your-cloud-connection-details',
  title: 'Obtain your Cloud connection details',
  description: 'Learn how to find the hostname, port, and credentials for your ClickHouse Cloud service so you can connect from external clients, CLIs, and applications.',
  href: '/core/get-started/quickstarts/obtain-your-cloud-connection-details',
  useCases: ['All'],
  products: ['Cloud'],
  level: 'Beginner'
}, {
  id: 'tutorial',
  title: 'Advanced tutorial',
  description: 'Learn how to ingest and query data in ClickHouse using a New York City taxi example dataset.',
  href: '/core/get-started/quickstarts/tutorial',
  useCases: [],
  products: [],
  level: 'Beginner'
}, {
  id: 'working-with-the-map-type',
  title: 'Working with the Map type in ClickHouse',
  description: 'Learn how to use the Map type in ClickHouse to store, query, and aggregate dynamic key-value data using OTel resource attributes as a practical example.',
  href: '/core/get-started/quickstarts/working-with-the-map-type',
  useCases: ['Observability'],
  products: ['Cloud', 'OSS'],
  level: 'Beginner'
}, {
  id: 'writing-queries',
  title: 'Selecting ClickHouse data',
  description: 'Learn how to write SELECT queries in ClickHouse to read and explore data, including basic syntax, WHERE clauses, ORDER BY, and JOIN.',
  href: '/core/get-started/quickstarts/writing-queries',
  useCases: ['All'],
  products: ['Cloud', 'OSS'],
  level: 'Beginner'
}];

<div className="relative overflow-hidden">
  <div className="absolute top-0 left-0 right-0 opacity-80">
    <img src="https://mintcdn.com/private-7c7dfe99-sync-clickhouse-operator-docs-7e82242/dQ4Y5ffi2aHPjikP/images/background-light.svg?fit=max&auto=format&n=dQ4Y5ffi2aHPjikP&q=85&s=88364532595f46e4ffe4550d721f8338" className="block dark:hidden pointer-events-none w-full h-auto" alt="Decorative background image." width="1152" height="388" data-path="images/background-light.svg" />

    <img src="https://mintcdn.com/private-7c7dfe99-sync-clickhouse-operator-docs-7e82242/dQ4Y5ffi2aHPjikP/images/background-dark.svg?fit=max&auto=format&n=dQ4Y5ffi2aHPjikP&q=85&s=91c5bb1840390a4addaaa6d6579d34fa" className="hidden dark:block pointer-events-none w-full h-auto" alt="Decorative background image." width="1152" height="388" data-path="images/background-dark.svg" />
  </div>

  <QuickStartsGrid quickStartsData={quickStartsData} featuredIds={featuredQuickStartIds} />
</div>
