diff --git a/README.md b/README.md index 41ad8753..4d26da55 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,292 @@ -# Keploy's blog with Next.js and WordPress +

+ Keploy Logo +

-## Configuration - -### Step 1. Prepare your WordPress site - -First, you need a WordPress site. There are many solutions for WordPress hosting or you could use a Local by flywheel for setting up WordPress locally. +

Keploy Blog

-Once the site is ready, you'll need to install the [WPGraphQL](https://www.wpgraphql.com/) plugin. It will add GraphQL API to your WordPress site, which we'll use to query the posts. Follow these steps to install it: +

+ The official blog for Keploy — live at keploy.io/blog +

-- Download the [WPGraphQL repo](https://github.com/wp-graphql/wp-graphql) as a ZIP archive. -- Inside your WordPress admin, go to **Plugins** and then click **Add New**. -- Click the **Upload Plugin** button at the top of the page and upload the WPGraphQL plugin. -- Once the plugin has been added, activate it from either the **Activate Plugin** button displayed after uploading or from the **Plugins** page. +

+ Next.js + TypeScript + Tailwind + WPGraphQL +

-#### GraphQL +--- -The [WPGraphQL](https://www.wpgraphql.com/) plugin also gives you access to a GraphQL IDE directly from your WordPress Admin, allowing you to inspect and play around with the GraphQL API. +## What is this? -### Step 2. Populate Content +A **Next.js (Pages Router)** blog application that powers the [Keploy Blog](https://keploy.io/blog). Content is authored in a headless **WordPress** instance and fetched at build time via the **WPGraphQL** plugin. The site is statically generated with **Incremental Static Regeneration (ISR)**, revalidating every 10 seconds for near-instant page loads and always-fresh content. -Inside your WordPress admin, go to **Posts** and start adding new posts: +--- -- We recommend creating at least **2 posts** -- Use dummy data for the content -- Pick an author from your WordPress users -- Add a **Featured Image**. You can download one from [Unsplash](https://unsplash.com/) -- Fill the **Excerpt** field +## Configuration -When you’re done, make sure to **Publish** the posts. +### Prerequisites -> **Note:** Only **published** posts and public fields will be rendered by the app +- **Node.js** ≥ 18 +- **npm** or **yarn** +- A WordPress instance with the [WPGraphQL](https://www.wpgraphql.com/) plugin installed and activated -### Step 3. Clone the repository +### 1. Clone the repo ```bash git clone https://github.com/keploy/blog-website.git cd blog-website ``` -### Step 4. Install dependencies +### 2. Install dependencies ```bash npm install - -# or - -yarn install ``` -### Step 5. Set up environment variables -Copy the .env.local.example file in this directory to .env.local (which will be ignored by Git): +### 3. Set up environment variables ```bash cp .env.local.example .env.local ``` -Then open .env.local and set WORDPRESS_API_URL to be the URL to your GraphQL endpoint in WordPress. For example: https://Testapp.com/graphql. +Edit `.env.local` and configure: -Your .env.local file should look like this: +```env +# Required — Your WordPress GraphQL endpoint +WORDPRESS_API_URL=https://wp.keploy.io/graphql -```bash -WORDPRESS_API_URL=... +# Optional — Only needed for preview mode +# WORDPRESS_AUTH_REFRESH_TOKEN= +# WORDPRESS_PREVIEW_SECRET= ``` -### Step 6. Run Next.js in development mode +### 4. Run the dev server + ```bash npm run dev +``` -# or +Open [http://localhost:3000/blog](http://localhost:3000/blog) — note the `/blog` base path. -yarn dev +### 5. Build for production + +```bash +npm run build +npm start ``` -Your blog should be up and running on http://localhost:3000! If it doesn't work, post on GitHub discussions. +## Contributing + +1. Fork the repository +2. Create a feature branch: `git checkout -b feat/my-change` +3. Commit your changes: `git commit -m "feat: add new feature"` +4. Push to your fork: `git push origin feat/my-change` +5. Open a Pull Request — the PR template will guide you + +The CI pipeline will automatically run a build check and Lighthouse audits on your PR. + +--- + +### Deployment + +The site is deployed on **Vercel**. CloudFront is configured to proxy `/blog/*` requests to the Vercel deployment, so CSS/JS assets resolve correctly under the `keploy.io` domain. + +> **Note:** The `basePath: '/blog'` and `assetPrefix: '/blog'` settings in `next.config.js` are critical for this routing to work. + +--- + +## Site Map + +All pages are served under the base path `https://keploy.io/blog` (locally at `http://localhost:3000/blog`). + +### Pages + +| S.No | Page | Live URL | File Location | Description | +|------|------|----------|---------------|-------------| +| 1 | **Home** | [keploy.io/blog](https://keploy.io/blog) | `pages/index.tsx` | Hero section with CTA buttons, top blogs (community + technology), testimonials marquee carousel | +| 2 | **Technology Listing** | [keploy.io/blog/technology](https://keploy.io/blog/technology) | `pages/technology/index.tsx` | Featured hero post + paginated grid of all technology category posts with infinite scroll | +| 3 | **Technology Post** | [keploy.io/blog/technology/\[slug\]](https://keploy.io/blog/technology/) | `pages/technology/[slug].tsx` | Individual technology blog post — includes sticky table of contents, syntax-highlighted code blocks, reading time, related posts, reviewing author, newsletter CTA | +| | | _Example:_ [keploy.io/blog/technology/api-testing-tools](https://keploy.io/blog/technology/api-testing-tools) | | | +| 4 | **Community Listing** | [keploy.io/blog/community](https://keploy.io/blog/community) | `pages/community/index.tsx` | Featured hero post + paginated grid of all community category posts with infinite scroll | +| 5 | **Community Post** | [keploy.io/blog/community/\[slug\]](https://keploy.io/blog/community/) | `pages/community/[slug].tsx` | Individual community blog post — same layout as technology posts (TOC, code blocks, related posts, etc.) | +| | | _Example:_ [keploy.io/blog/community/state-transition-testing](https://keploy.io/blog/community/state-transition-testing) | | | +| 6 | **Community Search** | [keploy.io/blog/community/search](https://keploy.io/blog/community/search) | `pages/community/search.tsx` | Full-text search scoped to community posts only | +| 7 | **Authors Listing** | [keploy.io/blog/authors](https://keploy.io/blog/authors) | `pages/authors/index.tsx` | Grid of all blog authors with avatars | +| 8 | **Author Profile** | [keploy.io/blog/authors/\[slug\]](https://keploy.io/blog/authors/) | `pages/authors/[slug].tsx` | Author bio, avatar, and all posts written by that author | +| | | _Example:_ [keploy.io/blog/authors/sancharini-panda](https://keploy.io/blog/authors/sancharini-panda) | | | +| 9 | **Tags Listing** | [keploy.io/blog/tag](https://keploy.io/blog/tag) | `pages/tag/index.tsx` | All tags displayed as cards with category-specific icons | +| 10 | **Tag Posts** | [keploy.io/blog/tag/\[slug\]](https://keploy.io/blog/tag/) | `pages/tag/[slug].tsx` | All posts filtered by a specific tag | +| | | _Example:_ [keploy.io/blog/tag/a2a](https://keploy.io/blog/tag/a2a) | | | +| 11 | **Global Search** | [keploy.io/blog/search](https://keploy.io/blog/search) | `pages/search.tsx` | Full-text search across all posts (technology + community) | +| 12 | **404** | [keploy.io/blog/404](https://keploy.io/blog/404) | `pages/404.tsx` | Custom animated "not found" page with Lottie animation | + +### URL Pattern Summary + +``` +https://keploy.io/blog/ +├── / → Home +├── /technology → Technology listing +│ └── /technology/{post-slug} → e.g., /technology/api-testing-tools +├── /community → Community listing +│ ├── /community/{post-slug} → e.g., /community/state-transition-testing +│ └── /community/search → Community-scoped search +├── /authors → All authors +│ └── /authors/{author-slug} → e.g., /authors/sancharini-panda +├── /tag → All tags +│ └── /tag/{tag-slug} → e.g., /tag/a2a +├── /search → Global search +└── /404 → Not found page +``` + +### API Routes + +| S.No | Route | Live URL | File Location | Description | +|------|-------|----------|---------------|-------------| +| 1 | `/api/search-all` | `keploy.io/blog/api/search-all` | `pages/api/search-all.ts` | Server-side full-text search across all posts, returns JSON | +| 2 | `/api/nav-latest` | `keploy.io/blog/api/nav-latest` | `pages/api/nav-latest.ts` | Fetches latest posts for the navbar "Recent Posts" dropdown | +| 3 | `/api/preview` | `keploy.io/blog/api/preview` | `pages/api/preview.ts` | Enters Next.js preview mode to render WordPress draft posts | +| 4 | `/api/exit-preview` | `keploy.io/blog/api/exit-preview` | `pages/api/exit-preview.ts` | Exits preview mode and returns to static pages | +| 5 | `/api/proxy-image` | `keploy.io/blog/api/proxy-image` | `pages/api/proxy-image.ts` | Proxies WordPress-hosted images to avoid CORS/CSP issues | + +### Navbar Structure + +The floating navbar is a mega-menu with multi-column dropdowns. Its full configuration lives in `config/nav.ts`. + +| Dropdown | Sections | Key Links | +|----------|----------|-----------| +| **Products** | Core Products, Key Features | Open Source Testing → [github.com/keploy/keploy](https://github.com/keploy/keploy), Enterprise Solution → [app.keploy.io](https://app.keploy.io), API Recording & Replay, Test Deduplication, Multi-Purpose Mocks | +| **Solutions** | Testing Types, Testing Methods | Test Data Generation, API Testing, Code Coverage, CI Testing, Regression Testing, Contract Testing | +| **Developers** | Documentation, Developer Resources | Getting Started → [keploy.io/docs](https://keploy.io/docs), API Reference, FAQs, Open Source Community, GitHub | +| **Blog** _(this site)_ | Technology, Community | [keploy.io/blog/technology](https://keploy.io/blog/technology), [keploy.io/blog/community](https://keploy.io/blog/community) | + +--- + +## Tech Stack + +| Layer | Technology | Used In | +|---|---|---| +| **Framework** | Next.js 18 (Pages Router, SSG + ISR) | Entire app | +| **Language** | TypeScript 4.7 | Entire app | +| **Styling** | Tailwind CSS 3 | All components | +| **Animations** | Framer Motion | `layout.tsx`, `PageLoader.tsx` (page transitions, loading) | +| **Animations** | GSAP | `subscribe-newsletter.tsx` (bunny animation) | +| **Animations** | React Spring | `header.tsx`, `post-preview.tsx`, `post-card.tsx`, slug pages (scroll-based spring animations) | +| **CMS** | WordPress + WPGraphQL | `lib/api.ts` (all data fetching) | +| **Code Highlighting** | Prism.js | `prism-loader.tsx` (syntax highlighting in blog posts) | +| **Code Editor** | CodeMirror + Dracula theme | `json-diff-viewer.tsx` (interactive code comparison) | +| **JSON Diffing** | json-diff-kit | `json-diff-viewer.tsx`, `post-body.tsx` | +| **Lottie Animations** | @lottiefiles/react-lottie-player | `PageLoader.tsx` (loading animation) | +| **UI Primitives** | Radix UI | `ui/accordion.tsx`, `ui/sheet.tsx`, `ui/navigation-menu.tsx` | +| **Icons** | Lucide React | `config/nav.ts`, navbar components | +| **Icons** | React Icons | `post-body.tsx`, `more-stories.tsx`, `NotFoundPage.tsx`, `tagIcons.ts` | +| **Date Formatting** | date-fns | `date.tsx` | +| **SEO** | JSON-LD Structured Data | `lib/structured-data.ts` (Organization, WebSite, BlogPosting, BreadcrumbList schemas) | +| **SEO** | Sitemap + robots.txt | `public/sitemap.xml`, `public/robots.txt` | +| **Analytics** | Google Analytics, Microsoft Clarity, Apollo | `layout.tsx` (tracking scripts) | +| **Deployment** | Vercel + CloudFront | Production at `keploy.io/blog` | +| **CI/CD** | GitHub Actions | `.github/workflows/build.yml`, `lighthouse_runner.yml` | + +--- + +## Project Structure + +``` +blog-website/ +├── pages/ # Next.js page routes (see Site Map above) +│ └── api/ # API routes +├── components/ # 47+ React components +│ ├── navbar/ # Floating navbar with mega-menu dropdowns +│ │ ├── FloatingNavbar.tsx # Navbar wrapper +│ │ ├── FloatingNavbarClient.tsx # Client-side navbar logic +│ │ ├── main-nav.tsx # Desktop navigation +│ │ ├── mobile-nav.tsx # Mobile navigation drawer +│ │ ├── github-stars.tsx # Live GitHub star counter +│ │ ├── vscode-number.tsx # VS Code installs counter +│ │ ├── nav-card.tsx # Navbar dropdown card +│ │ └── icons.tsx # SVG icon components +│ ├── ui/ # UI Components +│ │ ├── accordion.tsx +│ │ ├── button.tsx +│ │ ├── navigation-menu.tsx +│ │ └── sheet.tsx +│ ├── layout.tsx # Root layout: meta, footer, analytics, scroll-to-top +│ ├── post-body.tsx # Blog post content renderer with code blocks +│ ├── more-stories.tsx # Paginated post grid with infinite scroll +│ ├── testimonials.tsx # Testimonials marquee carousel +│ ├── topBlogs.tsx # Top blogs section (community + technology) +│ ├── TableContents.tsx # Sticky table of contents sidebar +│ ├── subscribe-newsletter.tsx # Newsletter subscription with GSAP animation +│ ├── footer.tsx # Global footer with links and badges +│ ├── json-diff-viewer.tsx # Interactive JSON diff comparison (CodeMirror) +│ └── ... +├── lib/ +│ ├── api.ts # All WordPress GraphQL queries & data fetching +│ ├── structured-data.ts # JSON-LD schema generators +│ └── constants.ts # Site-wide constants (OG image URL, etc.) +├── config/ +│ ├── nav.ts # Navbar mega-menu configuration (products, solutions, developers) +│ └── redirect.ts # URL redirect mappings +├── hooks/ # Custom React hooks +│ ├── useGithubStars.tsx # Fetches live GitHub star count +│ ├── useHeaderScroll.tsx # Show/hide header on scroll direction +│ └── useVSCodeInstalls.tsx # Fetches VS Code extension install count +├── services/ +│ ├── Tweets.tsx # Twitter/X testimonial data +│ └── constants.ts # Service-level constants +├── types/ # TypeScript type definitions +│ ├── post.ts +│ ├── author.ts +│ └── tag.ts +├── utils/ +│ ├── calculateReadingTime.ts # Reading time estimation +│ ├── tagIcons.ts # Tag → icon mapping +│ ├── sanitizeAuthorSlug.ts # Author URL sanitization +│ ├── sanitizeStringForUrl.ts # Generic URL sanitization +│ └── excerpt.ts # Post excerpt truncation +├── public/ +│ ├── images/ # Static images and illustrations +│ ├── avatars/ # Testimonial avatars +│ ├── favicon/ # Favicon set +│ ├── robots.txt # Crawl rules +│ └── sitemap.xml # Generated sitemap +├── styles/ +│ └── index.css # Global styles + Tailwind directives +├── .github/ +│ ├── workflows/ +│ │ ├── build.yml # CI build verification +│ │ ├── lighthouse_runner.yml # Lighthouse audits runner +│ │ └── lighthouse_comment.yml # Posts Lighthouse results to PRs +│ └── PULL_REQUEST_TEMPLATE.md +├── next.config.js # Next.js config (basePath: /blog, CSP headers, image domains) +├── tailwind.config.js # Tailwind theme extensions +└── package.json +``` + +--- + +## Key Features + +- **Headless WordPress CMS** — Content managed in WordPress, fetched via GraphQL at build time +- **ISR (Incremental Static Regeneration)** — Pages revalidate every 10 seconds for fresh content without full rebuilds +- **SEO-First** — JSON-LD structured data (Organization, WebSite, BlogPosting, BreadcrumbList), meta tags, Open Graph, sitemap, and robots.txt +- **Mega-Menu Navbar** — Multi-column floating navigation with product cards, solution links, and developer resources +- **Full-Text Search** — Client-side search with servr-side API backing (`/api/search-all`) +- **Pagination / Infinite Scroll** — Posts load progressively as the user scrolls +- **Syntax-Highlighted Code Blocks** — Prism.js for blog post code, CodeMirror for interactive JSON diffs +- **Table of Contents** — Auto-generated sticky sidebar TOC for blog posts +- **Testimonials Carousel** — Animated marquee showcase of community testimonials +- **Reading Time Estimates** — Calculated per-post reading duration +- **Preview Mode** — Authenticated preview of WordPress draft posts via `/api/preview` +- **Page Transitions** — Smooth fade-in animations via Framer Motion +- **Spring Animations** — Scroll-based animations on post cards and headers via React Spring +- **Newsletter Subscription** — Animated subscription form with GSAP bunny animation +- **Responsive Design** — Mobile-first layout with dedicated mobile navigation drawer +- **Lighthouse CI** — Automated performance, accessibility, and SEO audits on every PR + +--- + + +## License -For CSS files being rendered at vercel and not on keploy enpoint - we set generic redirection /blogs/* on cloudfront. +This project is part of the [Keploy](https://github.com/keploy) open-source ecosystem. diff --git a/components/Marquee.tsx b/components/Marquee.tsx index 4b6082a9..1c73fcd1 100644 --- a/components/Marquee.tsx +++ b/components/Marquee.tsx @@ -27,7 +27,7 @@ export function Marquee({ .map((_, i) => (
{children}
diff --git a/components/testimonials.tsx b/components/testimonials.tsx index 662d8fb3..b57e19bd 100644 --- a/components/testimonials.tsx +++ b/components/testimonials.tsx @@ -1,5 +1,4 @@ import React from "react"; -import { useRouter } from "next/router"; import { Marquee } from "./Marquee"; import Tweets from "../services/Tweets"; const firstRow = Tweets.slice(0, Tweets.length / 2); @@ -18,19 +17,25 @@ const ReviewCard = ({ id: string; content: string; }) => { - const { basePath } = useRouter(); - const isExternal = typeof avatar === "string" && /^https?:\/\//i.test(avatar); - const proxiedAvatar = isExternal ? `${basePath}/api/proxy-image?url=${encodeURIComponent(avatar)}` : avatar; + const fallbackAvatar = `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}&background=random&size=64`; + const localPlaceholder = "/blog/avatars/avatar-placeholder.svg"; return ( - +
{ + const img = e.target as HTMLImageElement; + if (img.src !== localPlaceholder) { + img.onerror = () => { img.src = localPlaceholder; }; + img.src = fallbackAvatar; + } + }} />
{name}
@@ -46,23 +51,22 @@ const ReviewCard = ({ const TwitterTestimonials = () => { return (
-

- What our community thinks -

-
- - +

+ What our community thinks +

+
+ + {firstRow.map((tweet) => ( ))} - + {secondRow.map((tweet) => ( ))} -
-
+ ); diff --git a/package-lock.json b/package-lock.json index 26a31355..0f92b1ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -270,7 +270,6 @@ "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.34.1.tgz", "integrity": "sha512-t1zK/l9UiRqwUNPm+pdIT0qzJlzuVckbTEMVNFhfWkGiBQClstzg+78vedCvLSX0xJEZ6lwZbPpnljL7L6iwMQ==", "license": "MIT", - "peer": true, "dependencies": { "@codemirror/state": "^6.4.0", "style-mod": "^4.1.0", @@ -1454,7 +1453,6 @@ "version": "18.2.36", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.36.tgz", "integrity": "sha512-o9XFsHYLLZ4+sb9CWUYwHqFVoG61SesydF353vFMMsQziiyRu8np4n2OYMUSDZ8XuImxDr9c5tR7gidlH29Vnw==", - "peer": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1465,7 +1463,6 @@ "version": "18.2.14", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.14.tgz", "integrity": "sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==", - "peer": true, "dependencies": { "@types/react": "*" } @@ -1524,7 +1521,6 @@ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", @@ -1796,7 +1792,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2185,7 +2180,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001541", "electron-to-chromium": "^1.4.535", @@ -2780,7 +2774,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", "dev": true, - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -2933,7 +2926,6 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, - "peer": true, "dependencies": { "array-includes": "^3.1.7", "array.prototype.findlastindex": "^1.2.3", @@ -4918,7 +4910,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -5098,7 +5089,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -5110,7 +5100,6 @@ "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -5808,7 +5797,6 @@ "version": "3.3.5", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz", "integrity": "sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==", - "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -6053,7 +6041,6 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/public/avatars/AndooBomber.png b/public/avatars/AndooBomber.png new file mode 100644 index 00000000..1f4bdc8f Binary files /dev/null and b/public/avatars/AndooBomber.png differ diff --git a/public/avatars/TadasG.png b/public/avatars/TadasG.png new file mode 100644 index 00000000..3f22405b Binary files /dev/null and b/public/avatars/TadasG.png differ diff --git a/public/avatars/avatar-placeholder.svg b/public/avatars/avatar-placeholder.svg new file mode 100644 index 00000000..2ace7c5a --- /dev/null +++ b/public/avatars/avatar-placeholder.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/avatars/kyongshiii06.png b/public/avatars/kyongshiii06.png new file mode 100644 index 00000000..d2f57450 Binary files /dev/null and b/public/avatars/kyongshiii06.png differ diff --git a/public/avatars/matsuu.png b/public/avatars/matsuu.png new file mode 100644 index 00000000..4ae225bd Binary files /dev/null and b/public/avatars/matsuu.png differ diff --git a/public/avatars/yadon.png b/public/avatars/yadon.png new file mode 100644 index 00000000..9989c91d Binary files /dev/null and b/public/avatars/yadon.png differ diff --git a/services/Tweets.tsx b/services/Tweets.tsx index 12492607..e0cbd01a 100644 --- a/services/Tweets.tsx +++ b/services/Tweets.tsx @@ -1,113 +1,113 @@ const Tweets = [ - { - avatar: - "https://pbs.twimg.com/profile_images/1569793803313201154/Lso5fu1j_400x400.jpg", - name: "Jay Vasant", - id: "__alter123", - post: "https://x.com/__alter123/status/1731985031521014236?s=20", - content: - "The point being, maintaining unit tests is terribly difficult, and in general requires more efforts than the actual development itself. I've hardly seen any startups even at good scale able to manage unit tests. If you really think it's a requirement you can try tools like Keploy. But I feel even if you honestly think, manual testing should be always feasible", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1422864637532332033/mC1Nx0vj_400x400.jpg", - name: "matsuu@充電期間", - id: "matsuu", - post: "https://x.com/matsuu/status/1747448928575099236?s=20", - content: - "Based on the communication trace information that can be obtained using eBPF, it is possible to generate a test and a stub server to be used when executing the test.", - }, + { + avatar: + "https://pbs.twimg.com/profile_images/1569793803313201154/Lso5fu1j_400x400.jpg", + name: "Jay Vasant", + id: "__alter123", + post: "https://x.com/__alter123/status/1731985031521014236?s=20", + content: + "The point being, maintaining unit tests is terribly difficult, and in general requires more efforts than the actual development itself. I've hardly seen any startups even at good scale able to manage unit tests. If you really think it's a requirement you can try tools like Keploy. But I feel even if you honestly think, manual testing should be always feasible", + }, + { + avatar: "/blog/avatars/matsuu.png", + name: "matsuu@充電期間", + id: "matsuu", + post: "https://x.com/matsuu/status/1747448928575099236?s=20", + content: + "Based on the communication trace information that can be obtained using eBPF, it is possible to generate a test and a stub server to be used when executing the test.", + }, + + { + avatar: + "https://pbs.twimg.com/profile_images/1860933223108452352/7AvlUHlk_400x400.jpg", + name: "Akash Singh", + id: "Kind_Of_Akash", + post: "https://x.com/Kind_Of_Akash/status/1754207010470736165?s=20", + content: + "Hey people, I wanted to share about my first month as an open source contributor at Keploy -Picked up 10 issues including bugs, features, documentation and opened 3 issues. -Submitted 8 PR's, out of which 2 have been merged and rest are on review", + }, + { + avatar: + "https://pbs.twimg.com/profile_images/1213737438830452736/5_5zXtXN_400x400.jpg", + name: "mugi", + id: "mugi_uno", + post: "https://x.com/mugi_uno/status/1745726154924003502?s=20", + content: + "I think the problem with mock data is that it is difficult to maintain, so if it makes it easier, I think it would be a good idea. The automated testing tool “Keploy” using eBPF is amazing", + }, + { + avatar: "/blog/avatars/kyongshiii06.png", + name: "きょん/kyong", + id: "kyongshiii06", + post: "https://x.com/kyongshiii06/status/1746532217336250821?s=20", + content: + "Keploy can record and replay complex, distributed API flows as mocks and stubs. It's like having a time machine for your tests—saving you tons of time.", + }, + { + avatar: + "https://pbs.twimg.com/profile_images/837573171427487744/IGQLsM55_400x400.jpg", + name: "やまもと@視力2.0", + id: "yamamoto_febc", + post: "https://x.com/yamamoto_febc/status/1755802346188390531?s=20", + content: + "It is quite easy to create normal tests. On the other hand, abnormal systems may be a little difficult. I think it's okay to use it only for normal systems.", + }, + { + avatar: "/blog/avatars/kyongshiii06.png", + name: "きょん/kyong", + id: "kyongshiii06", + post: "https://x.com/kyongshiii06/status/1753030333128495470?s=20", + content: + "I tried keploy, it was amazing. Just wrap and start docker, and then just hit the API with curl or the client and you'll be able to test more and more. This is the golden test.", + }, + { + avatar: + "https://pbs.twimg.com/profile_images/1741543460115812352/8x4aAI9k_400x400.jpg", + name: "Shivam Sourav Jha", + id: "ShivamSouravJha", + post: "https://x.com/ShivamSouravJha/status/1747517726749286713?s=20", + content: + "Why do I like keploy so much? Literally I see many tools and so hard to integrate. I mean update VScode , use the sdk , make this change make that change. With Keploy, don't worry buddy just run your application, we will literally do everything for you. You need to 0 efforts.", + }, + + + + { + avatar: "/blog/avatars/TadasG.png", + name: "TadasG", + id: "JustADude404", + post: "https://x.com/JustADude404/status/1746888711491424681?s=20", + content: + "Keploy is a tool which can automatically generate tests based on data from your running app. It simply attaches to your app, reads the data being passed through, and generates tests with real data. Pretty cool, huh?", + }, + + { + avatar: "/blog/avatars/yadon.png", + name: "yadon", + id: "Seipann11", + post: "https://x.com/Seipann11/status/1755989987039064103?s=20", + content: + "Keploy is seriously amazing, a genius tool crushing issues at lightning speed.", + }, + - { - avatar: - "https://pbs.twimg.com/profile_images/1860933223108452352/7AvlUHlk_400x400.jpg", - name: "Akash Singh", - id: "Kind_Of_Akash", - post: "https://x.com/Kind_Of_Akash/status/1754207010470736165?s=20", - content: - "Hey people, I wanted to share about my first month as an open source contributor at Keploy -Picked up 10 issues including bugs, features, documentation and opened 3 issues. -Submitted 8 PR's, out of which 2 have been merged and rest are on review", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1213737438830452736/5_5zXtXN_400x400.jpg", - name: "mugi", - id: "mugi_uno", - post: "https://x.com/mugi_uno/status/1745726154924003502?s=20", - content: - "I think the problem with mock data is that it is difficult to maintain, so if it makes it easier, I think it would be a good idea. The automated testing tool “Keploy” using eBPF is amazing", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1653250498127089665/x5RJbLq5_400x400.jpg", - name: "きょん/kyong", - id: "kyongshiii06", - post: "https://x.com/kyongshiii06/status/1746532217336250821?s=20", - content: - "Keploy can record and replay complex, distributed API flows as mocks and stubs. It's like having a time machine for your tests—saving you tons of time.", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1653250498127089665/x5RJbLq5_400x400.jpg", - name: "きょん/kyong", - id: "kyongshiii06", - post: "https://x.com/kyongshiii06/status/1753030333128495470?s=20", - content: - "I tried keploy, it was amazing. Just wrap and start docker, and then just hit the API with curl or the client and you'll be able to test more and more. This is the golden test.", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1741543460115812352/8x4aAI9k_400x400.jpg", - name: "Shivam Sourav Jha", - id: "ShivamSouravJha", - post: "https://x.com/ShivamSouravJha/status/1747517726749286713?s=20", - content: - "Why do I like keploy so much? Literally I see many tools and so hard to integrate. I mean update VScode , use the sdk , make this change make that change. With Keploy, don't worry buddy just run your application, we will literally do everything for you. You need to 0 efforts.", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/837573171427487744/IGQLsM55_400x400.jpg", - name: "やまもと@視力2.0", - id: "yamamoto_febc", - post: "https://x.com/yamamoto_febc/status/1755802346188390531?s=20", - content: - "It is quite easy to create normal tests. On the other hand, abnormal systems may be a little difficult. I think it's okay to use it only for normal systems.", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1712175220176355329/sLXbk_PZ_400x400.jpg", - name: "TadasG", - id: "JustADude404", - post: "https://x.com/JustADude404/status/1746888711491424681?s=20", - content: - "Keploy is a tool which can automatically generate tests based on data from your running app. It simply attaches to your app, reads the data being passed through, and generates tests with real data. Pretty cool, huh?", - }, + { + avatar: + "https://pbs.twimg.com/profile_images/1701251291861712897/PiTZ0UO7_400x400.jpg", + name: "Junichi.Y🐼@休職中", + id: "ymnk_8752", + post: "https://x.com/ymnk_8752/status/1745458928698450057?s=20", + content: + "It is amazing! I hear about eBPF a lot, but I don't know what it is.", + }, - { - avatar: - "https://pbs.twimg.com/profile_images/1482259385959464960/1pQMXwj7_400x400.jpg", - name: "yadon", - id: "Seipann11", - post: "https://x.com/Seipann11/status/1755989987039064103?s=20", - content: - "Keploy is seriously amazing, a genius tool crushing issues at lightning speed.", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1701251291861712897/PiTZ0UO7_400x400.jpg", - name: "Junichi.Y🐼@休職中", - id: "ymnk_8752", - post: "https://x.com/ymnk_8752/status/1745458928698450057?s=20", - content: - "It is amazing! I hear about eBPF a lot, but I don't know what it is.", - }, - { - avatar: - "https://pbs.twimg.com/profile_images/1604797450124144640/6G7KytX8_400x400.jpg", - name: "あんどーぼんばー", - id: "AndooBomber", - post: "https://x.com/AndooBomber/status/1747663021747691808?s=20", - content: "I tried Keploy, good tool.", - }, - ]; + { + avatar: "/blog/avatars/AndooBomber.png", + name: "あんどーぼんばー", + id: "AndooBomber", + post: "https://x.com/AndooBomber/status/1747663021747691808?s=20", + content: "I tried Keploy, good tool.", + }, +]; - export default Tweets; +export default Tweets; diff --git a/styles/index.css b/styles/index.css index 0b03c1d8..c69420b5 100644 --- a/styles/index.css +++ b/styles/index.css @@ -129,6 +129,11 @@ font-family: "Baloo 2", sans-serif; } +.marquee-mask { + -webkit-mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent); + mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent); +} + body { background: #fbfcff; color: #222222;