-
Notifications
You must be signed in to change notification settings - Fork 3
Add external link indicators to documentation #645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded@yamcodes has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 45 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
WalkthroughAdds an ExternalLink React component, SSR/CSR-safe URL utility, global CSS to render an external-arrow indicator, tests, MDX mapping so Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-authored-by: yamcodes <[email protected]>
Co-authored-by: yamcodes <[email protected]>
…ainability Co-authored-by: yamcodes <[email protected]>
Co-authored-by: yamcodes <[email protected]>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (6)
apps/www/app/globals.css (1)
15-18: URL-encode special characters in SVG data URI.The SVG data URL contains unencoded special characters (
<,>,") that may cause issues in some browsers or build tools. Encode them for maximum compatibility.🔎 Proposed fix with URL-encoded SVG
- --external-link-arrow: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 7h10v10"/><path d="M7 17 17 7"/></svg>'); + --external-link-arrow: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"%3E%3Cpath d="M7 7h10v10"/%3E%3Cpath d="M7 17 17 7"/%3E%3C/svg%3E');apps/www/components/ui/external-link.test.tsx (1)
16-79: Testing implementation details instead of behavior.The tests query for
querySelector("svg")to verify external link detection. This checks the implementation (that an SVG icon is rendered) rather than the behavior (that external links are visually distinguished). If the icon changes from SVG to a different element, tests break unnecessarily.Based on learnings: test component behavior and API, not implementation details.
Consider testing the presence of the icon by its accessible role or by verifying that the link element contains a child with
aria-hidden="true", or simply verify thatisExternallogic works correctly via unit tests of theisExternalUrlfunction separately.apps/www/components/ui/external-link.tsx (4)
7-9: Redundanthrefredefinition in ExternalLinkProps.Line 8 redefines
href?: string, butComponentProps<typeof FumadocsLink>already includeshref. This redefinition doesn't change the type (since both are optional strings) but adds unnecessary noise and could mask future type changes in the base component.🔎 Proposed simplification
If the base type already includes
href, simply extend without redefining:-export interface ExternalLinkProps extends ComponentProps<typeof FumadocsLink> { - href?: string; -} +export interface ExternalLinkProps extends ComponentProps<typeof FumadocsLink> {}Or use a type alias:
-export interface ExternalLinkProps extends ComponentProps<typeof FumadocsLink> { - href?: string; -} +export type ExternalLinkProps = ComponentProps<typeof FumadocsLink>;
14-19: Consider using a Set for O(1) domain lookups.
INTERNAL_DOMAINSis currently an array, resulting in O(n) lookups via.some()on line 42. Since the list is static and small, the performance impact is negligible, but using aSetis more idiomatic for membership checks and scales better if the list grows.🔎 Proposed refactor to use Set
-const INTERNAL_DOMAINS = [ +const INTERNAL_DOMAINS = new Set([ "arkenv.js.org", "www.arkenv.js.org", "localhost", "127.0.0.1", -]; +]);Then update line 42:
- if ( - INTERNAL_DOMAINS.some( - (domain) => hostname === domain || hostname.endsWith(`.${domain}`), - ) - ) { + for (const domain of INTERNAL_DOMAINS) { + if (hostname === domain || hostname.endsWith(`.${domain}`)) { + return false; + } + } - return false; - }Or keep as array with a comment noting the small size makes performance irrelevant.
33-36: Extract hardcoded fallback base URL to a named constant.The SSR fallback
"https://arkenv.js.org"is hardcoded and duplicates the domain fromINTERNAL_DOMAINS. Extracting it improves maintainability.🔎 Proposed refactor
+/** + * Default base URL for SSR environments where window is not available + */ +const DEFAULT_BASE_URL = "https://arkenv.js.org"; + /** * List of domains that should be treated as internal (same site) */ const INTERNAL_DOMAINS = [ "arkenv.js.org", // ... ]; function isExternalUrl(href: string | undefined): boolean { // ... try { const base = typeof window !== "undefined" ? window.location.origin - : "https://arkenv.js.org"; + : DEFAULT_BASE_URL;
24-60: Consider exportingisExternalUrlfor reuse and testability.The
isExternalUrlhelper contains complex logic with multiple edge cases (relative paths, protocols, domain matching, SSR handling). Exporting it would enable direct unit testing of this logic independently of the component, reducing the need for indirect testing via component rendering.Rationale
- Testability: Unit tests can directly verify
isExternalUrlbehavior for all edge cases without rendering components.- Reusability: Other parts of the codebase may need similar external URL detection.
- Clarity: The public API makes the component's behavior more transparent.
Example export:
/** * Checks if a URL is external (not same domain or not a relative path) + * @public */ -function isExternalUrl(href: string | undefined): boolean { +export function isExternalUrl(href: string | undefined): boolean {
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/www/app/globals.cssapps/www/components/ui/external-link.test.tsxapps/www/components/ui/external-link.tsxapps/www/mdx-components.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Prefertypeoverinterfacefor type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverageconsttype parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypeserror)
Useas constwhere appropriate for immutable values (useAsConstAssertionerror)
Don't reassign function parameters (noParameterAssignerror)
Place default parameters last in function signatures (useDefaultParameterLasterror)
Always initialize enum values (useEnumInitializerserror)
Declare one variable per statement (useSingleVarDeclaratorerror)
Avoid unnecessary template literals (noUnusedTemplateLiteralerror)
PreferNumber.parseIntover globalparseInt(useNumberNamespaceerror)
Use kebab-case for TypeScript filenames (e.g.,create-env.ts)
Use camelCase for function names (e.g.,createEnv)
Use PascalCase for type names (e.g.,ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
UseArkEnvErrorfor environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type
**/*.{ts,tsx}: UsecreateEnv(schema)function (or default import asarkenv) to create validated environment objects in TypeScript
Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Use ArkEnvError for environment variable errors instead of generic Error types
For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'deve...
Files:
apps/www/mdx-components.tsxapps/www/components/ui/external-link.test.tsxapps/www/components/ui/external-link.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Use self-closing JSX elements (
useSelfClosingElementserror)
Files:
apps/www/mdx-components.tsxapps/www/components/ui/external-link.test.tsxapps/www/components/ui/external-link.tsx
apps/www/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/www/.cursor/rules/posthog-integration.mdc)
apps/www/**/*.{ts,tsx,js,jsx}: If using TypeScript, use an enum to store feature flag names. If using JavaScript, store feature flag names as strings to an object declared as a constant to simulate an enum. Use UPPERCASE_WITH_UNDERSCORE naming convention for enum/const object members.
If a custom property for a person or event is referenced in two or more files or two or more callsites in the same file, use an enum or const object with UPPERCASE_WITH_UNDERSCORE naming convention, similar to feature flags.
Files:
apps/www/mdx-components.tsxapps/www/components/ui/external-link.test.tsxapps/www/components/ui/external-link.tsx
**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Co-locate tests with components:
Component.tsxnext toComponent.test.tsx
**/*.test.{ts,tsx}: Use Vitest for unit and integration tests
Test individual functions, components, and hooks in isolation with mocked dependencies in unit tests
Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Unit tests should execute in less than 100ms per test
Mock external dependencies (clipboard, network, etc.) in unit tests
Co-locate unit test files with source files using naming convention: source file → test file (e.g., create-env.ts → create-env.test.ts)
Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Do not test pure styling or CSS classes, library internals (Radix/shadcn), implementation details (hooks, setState, private variables), or visual variants in component tests
Use Testing Library with user-event for real user simulation in component tests
Query by role, name, label, and text (accessibility first) in component tests
Use beforeEach/afterEach for cleanup, not beforeAll/afterAll when possible
Keep tests fast, deterministic, and parallelizable
Mock at component boundaries (network, time, context)Create unit tests with
.test.tsor.test.tsxsuffix located alongside source files, testing individual functions and components in isolation with mocked dependencies
Files:
apps/www/components/ui/external-link.test.tsx
**/*.{test,integration.test}.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{test,integration.test}.{ts,tsx}: Use Vitest'sdescribe/itstructure for all test files
Test both success and failure cases in unit and integration tests
Mockprocess.envin unit tests to test different environment variable scenarios
Files:
apps/www/components/ui/external-link.test.tsx
🧠 Learnings (12)
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test component public API (props, events, and component contract), user behavior (clicks, typing, focus, keyboard, ARIA), state transitions, accessibility, and side effects in component tests
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-23T07:09:57.082Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.082Z
Learning: Applies to **/*.integration.test.{ts,tsx} : Create integration tests with `.integration.test.ts` or `.integration.test.tsx` suffix, testing how multiple units work together without mocking their interactions (except external APIs)
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.integration.test.{ts,tsx} : Integration tests should focus on component and hook interactions, function composition and data flow, real dependencies between units, and state synchronization across boundaries
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-23T07:09:57.082Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.082Z
Learning: Applies to **/*.test.{ts,tsx} : Create unit tests with `.test.ts` or `.test.tsx` suffix located alongside source files, testing individual functions and components in isolation with mocked dependencies
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.integration.test.{ts,tsx} : Test how multiple units (components, hooks, functions) work together without mocking their interactions in integration tests
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Do not test pure styling or CSS classes, library internals (Radix/shadcn), implementation details (hooks, setState, private variables), or visual variants in component tests
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Mock external dependencies (clipboard, network, etc.) in unit tests
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test component behavior, not aesthetics, and focus on what users can do and what the component guarantees through its API
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Unit tests should focus on individual function logic and edge cases, component rendering and props, error handling and validation, and type checking
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to **/*.test.{ts,tsx} : Test individual functions, components, and hooks in isolation with mocked dependencies in unit tests
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-12T13:20:01.954Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/test-patterns.mdc:0-0
Timestamp: 2025-12-12T13:20:01.954Z
Learning: Applies to packages/vite-plugin/src/**/*.test.ts : Test the Vite plugin using the with-vite-react example as a fixture and validate that the plugin works with real Vite projects
Applied to files:
apps/www/components/ui/external-link.test.tsx
📚 Learning: 2025-12-23T07:09:57.082Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.082Z
Learning: Applies to **/*.{test,integration.test}.{ts,tsx} : Use Vitest's `describe`/`it` structure for all test files
Applied to files:
apps/www/components/ui/external-link.test.tsx
🧬 Code graph analysis (1)
apps/www/mdx-components.tsx (1)
apps/www/components/ui/external-link.tsx (1)
ExternalLink(66-84)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: test-e2e (e2e)
- GitHub Check: test-e2e (a11y)
🔇 Additional comments (2)
apps/www/mdx-components.tsx (1)
13-13: LGTM! Clean MDX integration.The
ExternalLinkmapping and component order adjustment ensure that all MDX anchor tags use the custom component, and thatcustomComponentscorrectly overridetwoslashComponentsfor any overlapping keys.Also applies to: 33-33, 53-53
apps/www/components/ui/external-link.tsx (1)
76-81: Arrow icon rendering looks correct.The conditional rendering of
<ArrowUpRight>with appropriate sizing, opacity, andaria-hidden="true"is well-implemented. Note: ensure this doesn't conflict with the CSS-based arrow (see comment onapps/www/app/globals.css).
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
… color inheritance and explicitly setting `ArrowUpRight` stroke to `currentColor`.
… into a shared utility.
… link CSS selector.
… control link styling, refine CSS selectors, and update example README formatting.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
apps/www/content/docs/arkenv/index.mdx (1)
6-7: Unused imports after removing icon props.The
BookOpen,Rocket,Globe, andGitHubicons appear to be unused now that the icon props were removed from the Card components. Consider removing these imports to keep the file clean.🔎 Suggested cleanup
-import { BookOpen, Rocket, Globe } from "lucide-react"; -import { SiGithub as GitHub } from "@icons-pack/react-simple-icons";apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx (1)
6-6: Unused import after removing icon prop.The
Globeicon import is no longer used now that the icon prop was removed from the Card component.🔎 Suggested cleanup
-import { Globe } from "lucide-react";
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
apps/www/app/globals.cssapps/www/components/page/edit-on-github.tsxapps/www/components/ui/card.tsxapps/www/components/ui/external-link.tsxapps/www/content/docs/arkenv/index.mdxapps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdxapps/www/lib/utils/url.tsexamples/README.md
✅ Files skipped from review due to trivial changes (1)
- examples/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/www/app/globals.css
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
**/*.{ts,tsx}: Prefertypeoverinterfacefor type definitions in TypeScript
Use TypeScript 5.1+ features when appropriate
Leverageconsttype parameters for better inference in TypeScript
Use JSDoc comments for public APIs
Use tabs for indentation (configured in Biome)
Use double quotes for strings (configured in Biome)
Organize imports automatically (Biome handles this)
Avoid explicit types when TypeScript can infer them (noInferrableTypeserror)
Useas constwhere appropriate for immutable values (useAsConstAssertionerror)
Don't reassign function parameters (noParameterAssignerror)
Place default parameters last in function signatures (useDefaultParameterLasterror)
Always initialize enum values (useEnumInitializerserror)
Declare one variable per statement (useSingleVarDeclaratorerror)
Avoid unnecessary template literals (noUnusedTemplateLiteralerror)
PreferNumber.parseIntover globalparseInt(useNumberNamespaceerror)
Use kebab-case for TypeScript filenames (e.g.,create-env.ts)
Use camelCase for function names (e.g.,createEnv)
Use PascalCase for type names (e.g.,ArkEnvError)
Use UPPER_SNAKE_CASE for environment variables and constants
Include examples in JSDoc comments when helpful for public APIs
Document complex type logic with JSDoc comments
UseArkEnvErrorfor environment variable validation errors
Provide clear, actionable error messages that include the variable name and expected type
**/*.{ts,tsx}: UsecreateEnv(schema)function (or default import asarkenv) to create validated environment objects in TypeScript
Use built-in validators (host, port, url, email) from ArkEnv when available instead of custom ArkType schemas
Provide default values for optional environment variables using ArkType syntax (e.g., 'boolean = false')
Use ArkEnvError for environment variable errors instead of generic Error types
For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'deve...
Files:
apps/www/lib/utils/url.tsapps/www/components/ui/card.tsxapps/www/components/page/edit-on-github.tsxapps/www/components/ui/external-link.tsx
apps/www/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/www/.cursor/rules/posthog-integration.mdc)
apps/www/**/*.{ts,tsx,js,jsx}: If using TypeScript, use an enum to store feature flag names. If using JavaScript, store feature flag names as strings to an object declared as a constant to simulate an enum. Use UPPERCASE_WITH_UNDERSCORE naming convention for enum/const object members.
If a custom property for a person or event is referenced in two or more files or two or more callsites in the same file, use an enum or const object with UPPERCASE_WITH_UNDERSCORE naming convention, similar to feature flags.
Files:
apps/www/lib/utils/url.tsapps/www/components/ui/card.tsxapps/www/components/page/edit-on-github.tsxapps/www/components/ui/external-link.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/coding-guidelines.mdc)
Use self-closing JSX elements (
useSelfClosingElementserror)
Files:
apps/www/components/ui/card.tsxapps/www/components/page/edit-on-github.tsxapps/www/components/ui/external-link.tsx
🧠 Learnings (7)
📚 Learning: 2025-09-09T17:37:19.650Z
Learnt from: yamcodes
Repo: yamcodes/arkenv PR: 132
File: packages/arkenv/README.md:13-14
Timestamp: 2025-09-09T17:37:19.650Z
Learning: For yamcodes/arkenv project: Runtime support documentation should link to specific examples: Node.js (examples/basic), Bun (examples/with-bun), Vite (examples/with-vite-react-ts).
Applied to files:
apps/www/content/docs/arkenv/index.mdxapps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx
📚 Learning: 2025-12-26T19:27:11.710Z
Learnt from: danciudev
Repo: yamcodes/arkenv PR: 614
File: packages/vite-plugin/src/index.test.ts:641-654
Timestamp: 2025-12-26T19:27:11.710Z
Learning: In packages/vite-plugin/src/**/*.test.ts: The test suite uses `env.test` files (without leading dot) as test fixtures that are manually read by the `readTestConfig` helper function and stubbed into process.env with `vi.stubEnv`, not as files to be read by Vite's loadEnv during tests.
Applied to files:
apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use descriptive environment variable names that indicate purpose and format (e.g., DATABASE_URL, NODE_ENV, FEATURE_FLAG)
Applied to files:
apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx
📚 Learning: 2025-11-24T16:04:00.957Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/coding-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:04:00.957Z
Learning: Applies to **/*.{ts,tsx} : Use `ArkEnvError` for environment variable validation errors
Applied to files:
apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx
📚 Learning: 2025-11-24T16:03:45.295Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .cursor/rules/arktype.mdc:0-0
Timestamp: 2025-11-24T16:03:45.295Z
Learning: Applies to packages/arkenv/**/*.ts : Keep environment variable schemas readable and TypeScript-like using ArkType syntax
Applied to files:
apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : For environment schema definition, use ArkType string literal syntax for enumerated values (e.g., "'development' | 'production' | 'test'")
Applied to files:
apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx
📚 Learning: 2025-12-23T07:09:57.130Z
Learnt from: CR
Repo: yamcodes/arkenv PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-23T07:09:57.130Z
Learning: Applies to **/*.{ts,tsx} : Use `createEnv(schema)` function (or default import as `arkenv`) to create validated environment objects in TypeScript
Applied to files:
apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx
🧬 Code graph analysis (2)
apps/www/components/ui/card.tsx (1)
apps/www/lib/utils/url.ts (1)
isExternalUrl(15-52)
apps/www/components/ui/external-link.tsx (1)
apps/www/lib/utils/url.ts (1)
isExternalUrl(15-52)
🔇 Additional comments (8)
apps/www/components/page/edit-on-github.tsx (1)
31-32: LGTM!The
data-no-underlineanddata-no-arrowattributes appropriately opt this link out of the external link styling since it already has a dedicatedSquarePenicon and is styled as a button.apps/www/lib/utils/url.ts (2)
4-9: LGTM! Consider IPv6 localhost if needed.The internal domains list covers common cases well. The subdomain matching logic at line 35 correctly prevents suffix attacks (the leading dot ensures
evilarkenv.js.orgwon't matcharkenv.js.org).One minor consideration: if IPv6 localhost (
::1) is used in any environment, it won't be recognized as internal. This is likely fine for typical use cases.
15-52: Well-structured SSR/CSR-safe URL detection.The function handles the complexity of server vs client rendering appropriately. The fallback to treating parse failures as internal (line 50) is a safe default that prevents broken UI for malformed URLs.
apps/www/content/docs/arkenv/index.mdx (1)
30-31: LGTM!The Card components for external links now correctly rely on the enhanced Card component to auto-render the external link indicator, avoiding redundant icon prop usage.
apps/www/content/docs/vite-plugin/arkenv-in-viteconfig.mdx (1)
45-45: LGTM!The Card now correctly relies on the component's internal external link detection.
apps/www/components/ui/card.tsx (1)
8-18: LGTM! Clean external link augmentation logic.The approach of wrapping the title with the arrow indicator only when external is clean. The
group-hoveropacity transition provides good interactive feedback within the Card context.apps/www/components/ui/external-link.tsx (2)
8-10: Clean interface extension.Making
hrefexplicitly optional in the interface is appropriate sinceisExternalUrlhandlesundefinedgracefully by returningfalse.
26-32: LGTM! Arrow icon implementation.The inline styling with
align-middleand em-based sizing ensures the icon scales appropriately with the surrounding text. Usingaria-hidden="true"correctly marks this decorative icon.
…External` prop in Card component.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
External links in documentation now display arrow icons (↗) to indicate navigation away from the site, following modern web UX patterns.
Implementation
Hybrid Approach
<article>links starting withhttp://orhttps://, excluding same-domain (arkenv.js.org) and localhostExternalLinkwraps fumadocsLinkcomponent for programmatic controlHybrid approach necessary because fumadocs'
<include>directive processes markdown at build time, bypassing MDX component system for some links.CSS Custom Property
SSR-Safe Detection
Result
Links like "ArkType" and "Standard Schema" now show visual indicators for external navigation.
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
fonts.googleapis.com/usr/local/bin/node node ./node_modules/.bin/../next/dist/bin/next build(dns block)/usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/arkenv/arkenv/node_modules/.pnpm/[email protected]_@babel+[email protected]_@opentelemetry+[email protected]_@playwright+[email protected]_react-d_f42438f6717e44ec3de5d0c1806f5fb0/node_modules/next/dist/server/lib/start-server.js(dns block)https://api.github.com/repos/yamcodes/arkenv/usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/arkenv/arkenv/node_modules/.pnpm/[email protected]_@babel+[email protected]_@opentelemetry+[email protected]_@playwright+[email protected]_react-d_f42438f6717e44ec3de5d0c1806f5fb0/node_modules/next/dist/server/lib/start-server.js(http block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.