Skip to content

Instantly share code, notes, and snippets.

@marnocha
Created February 21, 2023 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marnocha/2c144914d70361cd925b73d729a57029 to your computer and use it in GitHub Desktop.
Save marnocha/2c144914d70361cd925b73d729a57029 to your computer and use it in GitHub Desktop.
Coveo Atomic Next.JS Sample code from my website
import {
AtomicBreadbox,
AtomicColorFacet,
AtomicDidYouMean,
AtomicFacet,
AtomicFacetManager,
AtomicLayoutSection,
AtomicLoadMoreResults,
AtomicNoResults,
AtomicNumericFacet,
AtomicNumericRange,
AtomicQueryError,
AtomicQuerySummary,
AtomicRatingFacet,
AtomicRatingRangeFacet,
AtomicRefineToggle,
AtomicSearchBox,
AtomicSearchInterface,
AtomicSearchLayout,
AtomicSortDropdown,
AtomicSortExpression,
AtomicTimeframe,
AtomicTimeframeFacet,
buildSearchEngine,
AtomicFormatCurrency,
AtomicResultBadge,
AtomicResultFieldsList,
AtomicResultImage,
AtomicResultDate,
AtomicResultLink,
AtomicResultList,
AtomicResultMultiValueText,
AtomicResultNumber,
AtomicResultPrintableUri,
AtomicResultRating,
AtomicResultSectionBadges,
AtomicResultSectionBottomMetadata,
AtomicResultSectionEmphasized,
AtomicResultSectionExcerpt,
AtomicResultSectionTitle,
AtomicResultSectionTitleMetadata,
AtomicResultSectionVisual,
AtomicResultText,
AtomicText,
Result,
AtomicSmartSnippet,
AtomicSmartSnippetSuggestions,
AtomicSmartSnippetFeedbackModal
} from '@coveo/atomic-react';
import type { NextPage } from 'next';
import React from 'react'
import dynamic from 'next/dynamic';
import { useMemo } from 'react';
import { GLOBAL_SITE_CONSTANTS } from '../data/siteMetadata';
const smartSnippetStyle = `
a, a:link, a:visited, a:focus, a:hover, a:active {
color: black;
}
`;
const Search: NextPage = () => {
const engine = useMemo(
() =>
buildSearchEngine({
configuration: {
accessToken: GLOBAL_SITE_CONSTANTS.COVEO_ACCESS_TOKEN,
organizationId: GLOBAL_SITE_CONSTANTS.COVEO_ORGANIZATION_ID,
search: {
pipeline: 'default',
searchHub: 'nextjs-search',
},
},
}),
[]
);
return (
<>
<div className='mx-auto pt-3 pb-2 bg-white h-auto text-black px-4 md:px-1 lg:px-10 min-h-[500px]'>
<div className="container max-w-[1240px] mx-auto">
<AtomicSearchInterface
engine={engine}
fieldsToInclude={[
'blog_categories',
'blog_tags',
'blog_title',
'blog_featuredimage',
'blog_description',
'blog_publicationdate',
'author',
'blog_author'
]}
>
<AtomicSearchLayout>
<AtomicLayoutSection section="search">
<AtomicSearchBox />
</AtomicLayoutSection>
<AtomicLayoutSection section="facets">
<AtomicFacet field="source" label="Source" numberOfValues={2} withSearch={false} />
<AtomicFacet field="blog_categories" label="Categories" numberOfValues={4} withSearch={false} />
<AtomicFacet field="blog_tags" label="Tags" numberOfValues={4} withSearch={true} isCollapsed={true} />
<AtomicFacet field="blog_author" label="Authors" numberOfValues={4} withSearch={true} isCollapsed={true} />
</AtomicLayoutSection>
<AtomicLayoutSection section="main">
<AtomicLayoutSection section="status">
<AtomicBreadbox />
<AtomicQuerySummary />
<AtomicRefineToggle />
<AtomicSortDropdown>
<AtomicSortExpression label="relevance" expression="relevancy" />
<AtomicSortExpression
label="Publish Date (most recent first)"
expression="blog_publicationdate descending"
/>
<AtomicSortExpression
label="Publish Date (least recent first)"
expression="blog_publicationdate ascending"
/>
</AtomicSortDropdown>
<AtomicDidYouMean />
</AtomicLayoutSection>
<AtomicLayoutSection section="results">
<AtomicQueryError />
<AtomicSmartSnippet
snippetStyle={smartSnippetStyle}
headingLevel={2}
>
</AtomicSmartSnippet>
<AtomicSmartSnippetSuggestions
snippetStyle={smartSnippetStyle}
headingLevel={2}
></AtomicSmartSnippetSuggestions>
<AtomicResultList
display="list"
imageSize="large"
template={MyTemplate}
density="normal"
/>
<AtomicQueryError />
<AtomicNoResults />
</AtomicLayoutSection>
<AtomicLayoutSection section="pagination">
<AtomicLoadMoreResults />
</AtomicLayoutSection>
</AtomicLayoutSection>
</AtomicSearchLayout>
</AtomicSearchInterface>
</div>
</div>
</>
)
};
const templateStyle = `
atomic-result-text {
color: black;
}
atomic-result-section-title {
font-weight: 700;
}
atomic-result-text:hover {
text-decoration: none !important;
}
atomic-result-link a:hover {
color: #888 !important;
text-decoration-line: none;
text-decoration: none !important;
text-decoration-thickness: 0px;
}
atomic-result-link:visited {
text-decoration-line: none;
text-decoration: none !important;
text-decoration-thickness: 0px;
}
atomic-result-link:active {
text-decoration-line: none;
text-decoration: none !important;
text-decoration-thickness: 0px;
}
atomic-result-section-visual {
height: 150px !important;
}
@media only screen and (min-width: 1287px) {
atomic-result-section-visual {
.result-root.with-sections.display-list.density-normal atomic-result-section-visual {
margin-right: 0rem !important;
}
}
.result-root.with-sections.display-list.density-normal atomic-result-section-visual {
margin-right: 0rem !important;
}
}
atomic-result-image {
place-items: center !important;
}
atomic-result-image img {
width: 285px !important;
height: auto !important;
}
`;
function ConvertToDisplayString(input: []) {
if(input && input.length > 0) {
return input.map(item => "" + item).join(", ");
}
else {
return "";
}
};
function MyTemplate(result: Result) {
return (
<>
<style>{templateStyle}</style>
<AtomicResultSectionVisual>
<AtomicResultImage field="blog_featuredimage" />
</AtomicResultSectionVisual>
<AtomicResultSectionTitle>
<AtomicResultLink />
</AtomicResultSectionTitle>
<AtomicResultSectionExcerpt>
<AtomicResultText field="blog_description" />
</AtomicResultSectionExcerpt>
<AtomicResultSectionBottomMetadata>
<>
<span className='hidden'><b>Relevancy Score:&nbsp;</b>{result.score}&nbsp;&nbsp;</span>
{
result.raw.blog_categories && (result.raw.blog_categories as []).length > 0 && <b>Categories:&nbsp;</b>
}
{
result.raw.blog_categories && (ConvertToDisplayString(result.raw.blog_categories as []))
}
<span>&nbsp;</span>
</>
</AtomicResultSectionBottomMetadata>
</>
);
};
export default dynamic(() => Promise.resolve(Search), {
ssr: false,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment