Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions packages/web/src/lib/components/Testimonial.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
export let authorName: string;
export let authorSubtitle: string;
export let testimonial: string;
</script>

<article class="flex h-full flex-col justify-between gap-6 rounded-xl border border-neutral-200 bg-white p-6 shadow-sm break-inside-avoid dark:border-neutral-800 dark:bg-neutral-900">
<p class="text-base leading-relaxed text-neutral-700 dark:text-neutral-200">
{testimonial}
</p>
<footer class="flex flex-col gap-1">
<span class="font-semibold text-neutral-900 dark:text-neutral-50">{authorName}</span>
<span class="text-sm text-neutral-600 dark:text-neutral-400">{authorSubtitle}</span>
</footer>
</article>
32 changes: 32 additions & 0 deletions packages/web/src/lib/components/TestimonialCollection.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang="ts">
import Testimonial from './Testimonial.svelte';

type TestimonialItem = {
authorName: string;
authorSubtitle: string;
testimonial: string;
/** The URL the testimonial was sourced from. */
source: string;
};

export let testimonials: TestimonialItem[] = [];

const { class: extraClass = '', ...restProps } = $$restProps;
</script>

<section
{...restProps}
class={`mx-auto w-full max-w-6xl ${extraClass}`.trim()}
>
<div class="columns-1 gap-6 sm:columns-2 lg:columns-3">
{#each testimonials as item, index (item.authorName + index)}
<a href={item.source} class={`block mb-6 break-inside-avoid no-underline ${index % 2 == 0 ? "skew-hover" : "skew-hover-left"}`}>
<Testimonial
authorName={item.authorName}
authorSubtitle={item.authorSubtitle}
testimonial={item.testimonial}
/>
</a>
{/each}
</div>
</section>
66 changes: 66 additions & 0 deletions packages/web/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ObsidianLogo from '$lib/components/ObsidianLogo.svelte';
import Logo from '$lib/components/Logo.svelte';
import Graph from '$lib/components/Graph.svelte';
import Section from '$lib/components/Section.svelte';
import TestimonialCollection from '$lib/components/TestimonialCollection.svelte';
import EmacsLogo from '$lib/components/EmacsLogo.svelte';
import HelixLogo from '$lib/components/HelixLogo.svelte';
import NeovimLogo from '$lib/components/NeovimLogo.svelte';
Expand All @@ -22,6 +23,7 @@ import WordPressLogo from '$lib/components/WordPressLogo.svelte';
import ZedLogo from '$lib/components/ZedLogo.svelte';
import EdgeLogo from '$lib/components/EdgeLogo.svelte';
import { browser } from '$app/environment';
import Testimonial from '$lib/components/Testimonial.svelte';

/**
* @param {string} keyword
Expand All @@ -33,6 +35,65 @@ function agentHas(keyword: string): boolean | undefined {

return navigator.userAgent.toLowerCase().includes(keyword.toLowerCase());
}


const testimonials = [
{
authorName: "Rich Edmonds",
authorSubtitle: "Lead PC Hardware Editor, XDA Developers",
testimonial: "Written in Rust, everything is processed in an instant and I find it neat to see the browser extension highlight words as I type, effectively checking per letter. And no account is required, allowing me to get up and running in no time.",
source: "https://www.xda-developers.com/ditched-grammarly-for-this-amazing-open-source-alternative/"
},
{
authorName: "Justin Pot",
authorSubtitle: "Tech journalist, Lifehacker",
testimonial: "Obsidian is my favorite productivity app, and Harper is a grammar checking tool that works well with it.",
source: "https://lifehacker.com/tech/harper-offline-alternative-to-grammarly?test_uuid=02DN02BmbRCcASIX6xMQtY9&test_variant=B"
},
{
authorName: "Filip Cujanovic",
authorSubtitle: "Chrome Extension Review",
testimonial: "Awesome extension! It's privacy focused, that means that every check it done locally on your computer, there is no server where your data goes! And because of that it's blazingly fast compared to Grammarly.",
source: "https://chromewebstore.google.com/detail/private-grammar-checker-h/lodbfhdipoipcjmlebjbgmmgekckhpfb/reviews"
},
{
authorName: "Tim Miller",
authorSubtitle: "Author, Obsidian Rocks",
testimonial: "Harper is great: it is discreet, fast, powerful, and private.",
source: "https://obsidian.rocks/resource-harper/"
},
{
authorName: "Prakash Joshi Pax",
authorSubtitle: "Writer, Medium",
testimonial: "What I loved about this tool is that it's private, and open source and really fast.",
source: "https://beingpax.medium.com/9-new-obsidian-plugins-you-need-to-check-out-today-d55dba29bfb8"
},
{
authorName: "imbolc",
authorSubtitle: "Chrome Extension Review",
testimonial: "I've been using Harper in Neovim for a long time and am glad to see it as an extension!",
source: "https://chromewebstore.google.com/detail/private-grammar-checker-h/lodbfhdipoipcjmlebjbgmmgekckhpfb/reviews"

},
{
authorName: "Martijn Gribnau",
authorSubtitle: "Software Engineer",
testimonial: "What a delightful way to check for flagrant spelling errors in markdown files. Thanks Harper authors!",
source: "https://gribnau.dev/posts/harper-cli/"
},
{
authorName: "Chloe Ferguson",
authorSubtitle: "Writer, We Are Founders",
testimonial: "Harper excels at catching the kinds of mistakes that matter in technical writing – improper capitalization, misspelled words, and awkward phrasing that can make documentation unclear.",
source: "https://www.wearefounders.uk/the-grammar-checker-that-actually-gets-developers-meet-harper/"
},
{
authorName: "Rogerio Taques",
authorSubtitle: "Chrome Extension Review",
testimonial: "I've been using Harper instead of Grammarly for a few months already, and I can't be happier! I can't wait to see the great improvement when this tool reaches version 1.0.0! Great job! I hope that, eventually, it will also support languages other than English.",
source: "https://chromewebstore.google.com/detail/private-grammar-checker-h/lodbfhdipoipcjmlebjbgmmgekckhpfb/reviews"
},
];
</script>

<main class="mx-auto flex w-full max-w-5xl flex-col gap-12 py-12">
Expand Down Expand Up @@ -232,6 +293,11 @@ function agentHas(keyword: string): boolean | undefined {
</svelte:fragment>
</Section>

<Section>
<svelte:fragment slot="title">Loved by Thousands</svelte:fragment>
<TestimonialCollection testimonials={testimonials} />
</Section>

<Section id="faqs">
<svelte:fragment slot="title">FAQs</svelte:fragment>
<div class="space-y-4">
Expand Down
Loading