-
Notifications
You must be signed in to change notification settings - Fork 945
Docs revamp #1042
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
base: main
Are you sure you want to change the base?
Docs revamp #1042
Conversation
- Removed the hast package from dependencies. - Added @types/hast and @types/react-dom to devDependencies for improved type support. - Updated versions of @types/react-dom and related packages in pnpm-lock.yaml for consistency.
…omponent - Introduced a new optional `title` prop in the Link component for enhanced accessibility. - Modified the `breadcrumbs` type in the SEO component to allow optional `url` properties for improved flexibility. - Cleaned up formatting in the SEO component for better readability.
- Removed outdated reference to `next/navigation-types/compat/navigation`. - Updated the link for TypeScript configuration documentation to the correct page.
- Introduced a `shouldWrapInFrame` function to determine if images should be wrapped in a Frame for zooming, excluding certain patterns. - Updated the Image component to conditionally wrap images in a Frame based on the new logic. - Added support for standard markdown images by mapping the `img` tag to the Image component in relevant pages.
…umentation - Updated .env.example to include Meilisearch configuration for local development. - Modified docker-compose.yml to adjust the scraping command for local indexing. - Enhanced meilisearch-docs-scraper.config.json with stop URLs to refine scraping. - Updated README.md to include prerequisites for enabling local search functionality. - Improved sidebar component styling for better visual indication of the current section.
Manually port commits ef9c174 and b56bc98 from main: - Add "Last updated" date to docs/guides pages using git history - Fix API token header: Team-Access-Token → Authorization: Bearer - Migrate team → workspace terminology across documentation - Rename teams.md → workspaces.md and update all internal links
Resolved conflicts by keeping docs revamp structure: - Removed files that were reorganized/deleted in the revamp - Kept new file locations (e.g., content/docs/projects/workspaces.md)
|
🚅 Deployed to the docs-pr-1042 environment in 🪄 *.railway.com
5 services not affected by this PR
|
| const searchSessionId = useMemo(() => { | ||
| if (typeof window === "undefined") return ""; | ||
| return `search_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`; | ||
| }, []); |
Check failure
Code scanning / CodeQL
Insecure randomness High
Math.random()
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 14 hours ago
General fix: replace the use of Math.random() with a cryptographically secure random source when generating identifiers that are treated as session IDs. In browsers, this means using crypto.getRandomValues to obtain random bytes and encoding them as a string.
Best way to fix this code without changing existing functionality: keep the same search_<timestamp>_<random> format but implement a small helper function that uses window.crypto.getRandomValues to generate a random string instead of Math.random().toString(36).substring(2, 9). We can scope this helper inside useSearchAnalytics (or above it) so we don’t affect other files. If window.crypto is not available for some reason, we can conservatively fall back to Math.random() to preserve behavior, but the primary path will be cryptographically secure in browsers where crypto exists, which is the normal case for React apps using posthog-js.
Concrete changes in src/hooks/use-search-analytics.ts:
- Add a small helper function (e.g.,
generateSecureRandomString) to generate a base-36 string of length 7 usingwindow.crypto.getRandomValues(new Uint32Array(1)). - Update the
useMemothat createssearchSessionIdso that:- It checks for
window.cryptoand usesgenerateSecureRandomString()when available. - Optionally falls back to the existing
Math.random()behavior ifcryptois not present, avoiding runtime errors in edge environments.
- It checks for
- Keep the existing timestamp prefix and ID shape (
search_${Date.now()}_<random>), so all existing downstream usages and analytics dashboards remain compatible.
No new imports are needed, since window.crypto is part of the web platform.
-
Copy modified lines R71-R85 -
Copy modified lines R95-R96
| @@ -68,6 +68,21 @@ | ||
| } | ||
|
|
||
| /** | ||
| * Generate a cryptographically secure random string. | ||
| * Falls back to Math.random if crypto is unavailable. | ||
| */ | ||
| function generateSecureRandomString(length: number): string { | ||
| if (typeof window !== "undefined" && window.crypto && window.crypto.getRandomValues) { | ||
| const array = new Uint32Array(1); | ||
| window.crypto.getRandomValues(array); | ||
| return array[0].toString(36).substring(2, 2 + length); | ||
| } | ||
|
|
||
| // Fallback for environments without crypto; preserves previous behavior pattern. | ||
| return Math.random().toString(36).substring(2, 2 + length); | ||
| } | ||
|
|
||
| /** | ||
| * Hook for tracking search analytics in PostHog | ||
| */ | ||
| export function useSearchAnalytics() { | ||
| @@ -77,7 +92,8 @@ | ||
| // Generate a unique search session ID for correlating events | ||
| const searchSessionId = useMemo(() => { | ||
| if (typeof window === "undefined") return ""; | ||
| return `search_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`; | ||
| const randomPart = generateSecureRandomString(7); | ||
| return `search_${Date.now()}_${randomPart}`; | ||
| }, []); | ||
|
|
||
| /** |
| current = current[key] as Record<string, unknown>; | ||
| } | ||
|
|
||
| current[keys[keys.length - 1]] = value; |
Check warning
Code scanning / CodeQL
Prototype-polluting function Medium
here
current
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 14 hours ago
In general, to fix deep-assignment/prototype-pollution issues, you must prevent dangerous property names (__proto__, constructor, and optionally prototype) from being traversed or assigned, or require that you only recurse into/assign existing own properties on a known-safe object. Here, the minimal and safest fix is to block those special keys when iterating through keys and when setting the final property.
Best single fix without changing existing functionality for valid inputs:
- Add a small helper
isSafeKey(key: string): booleanthat returnsfalsefor__proto__,constructor, andprototype, andtrueotherwise. - In the
forloop at lines 385–390, skip any segment that is not a safe key so we never rebindcurrenttoObject.prototypeor its constructor. - Before the final assignment at line 393, check that the last key is safe; if not, return without doing anything.
- The rest of the behavior (creating intermediate objects when missing / not objects, and assigning
valueat the leaf) remains unchanged for all non-dangerous keys.
All needed changes are contained within src/components/graphql-code-tabs.tsx in the region around setNestedValue. No additional imports or external libraries are required.
-
Copy modified lines R387-R390 -
Copy modified lines R397-R403 -
Copy modified lines R406-R409
| @@ -384,15 +384,29 @@ | ||
|
|
||
| for (let i = 0; i < keys.length - 1; i++) { | ||
| const key = keys[i]; | ||
| // Guard against prototype pollution through special keys | ||
| if (!isSafeKey(key)) { | ||
| return; | ||
| } | ||
| if (!(key in current) || typeof current[key] !== "object") { | ||
| current[key] = {}; | ||
| } | ||
| current = current[key] as Record<string, unknown>; | ||
| } | ||
|
|
||
| current[keys[keys.length - 1]] = value; | ||
| const lastKey = keys[keys.length - 1]; | ||
| // Guard against prototype pollution on final assignment | ||
| if (!isSafeKey(lastKey)) { | ||
| return; | ||
| } | ||
|
|
||
| current[lastKey] = value; | ||
| } | ||
|
|
||
| function isSafeKey(key: string): boolean { | ||
| return key !== "__proto__" && key !== "constructor" && key !== "prototype"; | ||
| } | ||
|
|
||
| // Helper: Get a nested value using dot notation path | ||
| function getNestedValue(obj: Record<string, unknown>, path: string): unknown { | ||
| const keys = path.split("."); |
Rename url to baseUrl for clarity and fix breadcrumb schema URLs to include the full base URL prefix for proper structured data.
- Add logo, search button, and theme switcher to TopNav - Make top nav always visible with sticky positioning and backdrop blur - Remove header section from sidebar (logo, badge, theme switcher, search) - Update sidebar positioning to account for sticky top nav height - Update page layout to accommodate new structure - Add support for sidebar sections without titles - Update active state styling for consistency
- Update sidebar item active state styling with background highlight - Update parent highlighted state to use font-medium - Add Quick Start to first sidebar section and remove Overview title - Fix TOC IntersectionObserver rootMargin for sticky top nav height
- Replace text-based list with card grid (Quickstart, AI, CLI, Templates) - Add gradient backgrounds with light/dark mode variants for each card - Redesign footer with social icons layout - Remove unused A helper component

Current
New
This PR contains a comprehensive revamp of the Railway docs
New Information Architecture
New content + style guide
Design improvements
Technical Changes