-
Notifications
You must be signed in to change notification settings - Fork 2
feat: initial sveltekit + skeleton setup #1
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?
Conversation
WalkthroughThis change establishes the foundational structure and configuration for a SvelteKit-based web application named AxonotesHomepage. It introduces internationalization (i18n) support, theming, project metadata, server hooks, ESLint and Prettier configurations, Tailwind CSS setup, GitHub workflows, and multiple Svelte components for pages, layouts, navigation, and UI elements. The project is prepared for multilingual content, accessibility, and modern development workflows. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Browser
participant SvelteKit Server
participant Paraglide i18n
participant GitHub API
participant NodeCache
User->>Browser: Requests a page (e.g., /features)
Browser->>SvelteKit Server: Sends HTTP request
SvelteKit Server->>Paraglide i18n: Determines language context
SvelteKit Server->>NodeCache: Checks for cached features data
alt Cache hit and fresh
NodeCache-->>SvelteKit Server: Returns cached features
else Cache miss or stale
SvelteKit Server->>GitHub API: Fetches issues with "feature" label (paginated)
GitHub API-->>SvelteKit Server: Returns issues
SvelteKit Server->>NodeCache: Stores features in cache
end
SvelteKit Server-->>Browser: Returns rendered page with localized content and features
Browser->>User: Displays page with navigation, theming, and i18n
Possibly related PRs
Suggested reviewers
Poem
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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: 6
🧹 Nitpick comments (4)
.gitignore (1)
1-24
: Comprehensive .gitignore setup
The entries cover Node modules, OS files, build outputs, Vite timestamps, and environment files with selective un‐ignores. Consider also ignoring editor directories like.vscode/
if team members use VSCode, to prevent local settings from being committed.src/routes/+page.svelte (1)
1-2
: Add semantic structure and metadata.
The static markup is valid, but for improved accessibility, SEO, and semantics, wrap the content in a<main>
tag and include a<svelte:head>
block to set the page<title>
.Apply this diff:
--- src/routes/+page.svelte +++ src/routes/+page.svelte @@ -1,2 +1,11 @@ -<h1>Welcome to SvelteKit</h1> -<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p> +<svelte:head> + <title>Welcome to Axonotes</title> +</svelte:head> + +<main> + <h1>Welcome to SvelteKit</h1> + <p> + Visit + <a href="https://svelte.dev/docs/kit" target="_blank" rel="noopener noreferrer"> + the SvelteKit docs + </a> to get started. + </p> +</main>.idea/AxonotesHomepage.iml (1)
1-12
: Avoid committing IDE-specific files
Storing.idea
module files in version control can lead to merge conflicts and leak user-specific settings. It’s best practice to exclude.idea/
and.iml
files via the project’s root.gitignore
.Consider removing this file from the repo and adding to
.gitignore
:.idea/ *.imlREADME.md (1)
22-26
: Clarify dev server invocation flags
Usingnpm run dev -- --open
only works if yourdev
script forwards flags to SvelteKit. Confirm that yourpackage.json
includes:"scripts": { "dev": "svelte-kit dev --open" }or adjust the README to match the actual script definition.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (2)
bun.lock
is excluded by!**/*.lock
static/favicon.png
is excluded by!**/*.png
📒 Files selected for processing (20)
.gitignore
(1 hunks).idea/.gitignore
(1 hunks).idea/AxonotesHomepage.iml
(1 hunks).idea/modules.xml
(1 hunks).idea/vcs.xml
(1 hunks).npmrc
(1 hunks).prettierignore
(1 hunks).prettierrc
(1 hunks)README.md
(1 hunks)eslint.config.js
(1 hunks)package.json
(1 hunks)src/app.css
(1 hunks)src/app.d.ts
(1 hunks)src/app.html
(1 hunks)src/lib/index.ts
(1 hunks)src/routes/+layout.svelte
(1 hunks)src/routes/+page.svelte
(1 hunks)svelte.config.js
(1 hunks)tsconfig.json
(1 hunks)vite.config.ts
(1 hunks)
🔇 Additional comments (12)
src/lib/index.ts (1)
1-1
: Placeholder file is appropriate
This guidance comment aligns with SvelteKit’s$lib
convention. Once you start adding shared utilities, remember to export them here for clean imports..prettierignore (1)
1-6
: Lock files excluded from formatting
Ignoring the various lock files ensures Prettier focuses on source code only. This list looks complete for npm, pnpm, yarn, and bun lock formats..npmrc (1)
1-1
: Verify engine-strict enforcement
Theengine-strict=true
setting will only apply if you have declared anengines
field inpackage.json
. Please confirm that yourpackage.json
specifies the required Node.js version(s) so this restriction takes effect during installs..idea/modules.xml (1)
1-8
: IntelliJ IDEA modules configuration is correct.
This file sets up the project modules for IntelliJ IDEA. Ensure your team agrees on committing the.idea
folder contents; otherwise, consider moving these settings to a shared template or excluding them..idea/.gitignore (1)
1-8
: IDE-specific ignore rules are in place.
This file correctly excludes workspace, shelf, HTTP Requests, and data source local files from version control. If you intend to commit.iml
andmodules.xml
, ensure no conflicting entries exist in the root.gitignore
.vite.config.ts (1)
1-6
:✅ Verification successful
Verify Tailwind CSS plugin import
The importimport tailwindcss from '@tailwindcss/vite';
is not part of the official Tailwind CSS/Vite integration. Double-check that@tailwindcss/vite
exists in your dependencies and is intended. Typically Tailwind is configured via PostCSS (postcss.config.js
) andtailwind.config.js
, without a Vite plugin, or via a community plugin likevite-plugin-windicss
.To confirm installation, run:
🏁 Script executed:
#!/bin/bash rg '"@tailwindcss/vite"' package.jsonLength of output: 72
🌐 Web query:
npm package @tailwindcss/vite
💡 Result:
The
@tailwindcss/vite
package is a Vite plugin that integrates Tailwind CSS directly into your Vite project, streamlining the setup process and enhancing development efficiency. This plugin is particularly beneficial for projects using Tailwind CSS version 4 and later, as it simplifies the configuration by eliminating the need for a separate PostCSS setup.Installation:
To incorporate
@tailwindcss/vite
into your project, execute the following command:npm install tailwindcss @tailwindcss/viteConfiguration:
After installation, configure the plugin in your
vite.config.js
file:import { defineConfig } from 'vite'; import tailwindcss from '@tailwindcss/vite'; export default defineConfig({ plugins: [ tailwindcss(), // ...other plugins ], });This setup ensures that Tailwind CSS is seamlessly integrated into your Vite build process.
Usage:
In your main CSS file (e.g.,
src/index.css
), import Tailwind's base, components, and utilities:@import 'tailwindcss';This directive includes Tailwind's predefined styles into your project.
Additional Considerations:
Tailwind CSS Version: Ensure that your project is using Tailwind CSS version 4 or later to fully leverage the capabilities of
@tailwindcss/vite
.Vite Configuration: If you encounter issues related to module resolution, such as errors indicating that
@tailwindcss/vite
is an ESM-only package, consider renaming yourvite.config.js
tovite.config.mjs
to align with the module system. (stackoverflow.com)By following these steps, you can effectively integrate Tailwind CSS into your Vite project, benefiting from a more streamlined and efficient development workflow.
Citations:
No action needed for Tailwind CSS plugin import
The@tailwindcss/vite
package is a valid, officially supported Tailwind CSS v4+ plugin for Vite (confirmed in package.json and documentation). Your import and plugin configuration invite.config.ts
are correct.src/app.d.ts (1)
1-14
: Scaffolded declaration file looks good
Providing a globalApp
namespace for future customization aligns with SvelteKit’s best practices. The placeholder interfaces andexport {}
ensure the file is treated as a module and ready for extension.tsconfig.json (1)
1-19
: TypeScript configuration looks goodThe TypeScript configuration is well-structured with appropriate settings for a SvelteKit project. Setting
strict: true
is a good practice for catching type errors early, and the inclusion of source maps will help with debugging. The comments explaining path aliases and include/exclude handling provide valuable guidance for future maintenance.svelte.config.js (1)
1-18
: SvelteKit configuration is properly set upThe configuration uses the auto adapter which is ideal for an initial setup as it supports multiple deployment environments. The inclusion of vitePreprocess is correct for handling Svelte files with Vite. The comments provide good guidance on adapter selection for future reference.
src/app.html (1)
1-12
: HTML template follows SvelteKit best practicesThe template includes all necessary SvelteKit placeholders and optimizations like data-sveltekit-preload-data="hover" for improved performance. The integration with Skeleton UI via the data-theme="cerberus" attribute is properly implemented.
eslint.config.js (1)
1-36
: ESLint configuration is comprehensive but has one considerationThe ESLint configuration correctly integrates JavaScript, TypeScript, Svelte, and Prettier rules using the modern flat config format. The setup for Svelte files with TypeScript support is properly configured.
Note: The 'no-undef' rule is turned off globally (line 23). While this is common in TypeScript projects since TypeScript's type checker handles this, be aware that this could potentially allow undeclared variables to pass linting. Consider if this aligns with your team's preferences.
package.json (1)
1-5
: Metadata fields are well-defined
The project name, privacy flag, version, and module type are correctly specified for a private SvelteKit project.
.prettierrc
Outdated
"files": "*.svelte", | ||
"options": { |
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.
🛠️ Refactor suggestion
Ensure Svelte override covers nested files.
The pattern "*.svelte"
only matches root‐level files. To target all Svelte components (e.g., in src/routes
or src/lib
), update to "**/*.svelte"
.
--- .prettierrc
+++ .prettierrc
@@ -9,4 +9,4 @@
- {
- "files": "*.svelte",
+ {
+ "files": "**/*.svelte",
"options": {
"parser": "svelte"
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"files": "*.svelte", | |
"options": { | |
{ | |
"files": "**/*.svelte", | |
"options": { | |
"parser": "svelte" | |
} | |
} |
🤖 Prompt for AI Agents
In the .prettierrc file at lines 9 to 10, the override pattern for Svelte files
uses "*.svelte", which only matches files in the root directory. Change this
pattern to "**/*.svelte" to ensure it matches all Svelte files recursively in
nested directories like src/routes or src/lib.
src/routes/+layout.svelte
Outdated
let { children } = $props(); | ||
</script> | ||
|
||
{@render children()} |
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.
🛠️ Refactor suggestion
Use SvelteKit’s built-in slot API instead of $props()
and {@render}
In SvelteKit layouts, the recommended pattern is to use <slot />
to render child routes. The current use of let { children } = $props()
and {@render children()}
is atypical and may not work as expected.
Proposed diff:
--- src/routes/+layout.svelte
3,7c3,4
- let { children } = $props();
-</script>
-
-{@render children()}
+ </script>
+
+ <slot />
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
let { children } = $props(); | |
</script> | |
{@render children()} | |
<script> | |
</script> | |
<slot /> |
🤖 Prompt for AI Agents
In src/routes/+layout.svelte around lines 3 to 7, replace the use of let {
children } = $props() and {@render children()} with the standard SvelteKit slot
API by removing those lines and adding a <slot /> element to render child routes
properly. This aligns with SvelteKit conventions and ensures correct rendering
of nested content.
package.json
Outdated
"scripts": { | ||
"dev": "vite dev", | ||
"build": "vite build", | ||
"preview": "vite preview", | ||
"prepare": "svelte-kit sync || echo ''", | ||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | ||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", | ||
"format": "prettier --write .", | ||
"lint": "prettier --check . && eslint ." | ||
}, |
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.
Use SvelteKit CLI instead of raw Vite commands
SvelteKit projects conventionally use the svelte-kit
commands to ensure proper adapter integration, routing, and environment setup. Additionally, the prepare
script should not silently swallow errors.
Apply this diff:
--- a/package.json
+++ b/package.json
@@ -7,10 +7,10 @@
- "dev": "vite dev",
- "build": "vite build",
- "preview": "vite preview",
- "prepare": "svelte-kit sync || echo ''",
+ "dev": "svelte-kit dev",
+ "build": "svelte-kit build",
+ "preview": "svelte-kit preview",
+ "prepare": "svelte-kit sync",
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
"scripts": { | |
"dev": "vite dev", | |
"build": "vite build", | |
"preview": "vite preview", | |
"prepare": "svelte-kit sync || echo ''", | |
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | |
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", | |
"format": "prettier --write .", | |
"lint": "prettier --check . && eslint ." | |
}, | |
"scripts": { | |
"dev": "svelte-kit dev", | |
"build": "svelte-kit build", | |
"preview": "svelte-kit preview", | |
"prepare": "svelte-kit sync", | |
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | |
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", | |
"format": "prettier --write .", | |
"lint": "prettier --check . && eslint ." | |
}, |
🤖 Prompt for AI Agents
In package.json lines 6 to 15, replace the raw Vite commands in the "dev",
"build", and "preview" scripts with their corresponding "svelte-kit" CLI
commands to ensure proper SvelteKit integration. Also, update the "prepare"
script to run "svelte-kit sync" without swallowing errors by removing the "||
echo ''" part so any failures are visible.
Signed-off-by: isvladu <[email protected]>
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: 0
🧹 Nitpick comments (2)
.gitignore (2)
91-99
: Deduplicate build entries in SvelteKit section
You have both/build
(line 19) andbuild/
(line 93) entries. Consider removing one to avoid redundancy and simplify maintenance.Proposed diff:
- build/ # For SvelteKit adapter-static or older Svelte projects
112-119
: Clarify optional lockfile ignores
The commented-out lockfile ignore entries may confuse contributors. Clarify the intent or remove these lines if lockfiles should always be committed.Example diff:
-# package-lock.json -# yarn.lock -# pnpm-lock.yaml +# If you prefer to ignore lockfiles, uncomment the following: +# package-lock.json +# yarn.lock +# pnpm-lock.yaml
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
📒 Files selected for processing (1)
.gitignore
(1 hunks)
🔇 Additional comments (14)
.gitignore (14)
1-9
: Comprehensive log exclusion section
This block effectively ignores various log files and directories (logs
,*.log
,npm-debug.log*
, etc.), covering most common cases.
10-12
: Diagnostic report patterns
Correctly ignores Node.js diagnostic reports (report.<version>.json
).
13-20
: Output directories exclusion
Appropriately excludes build/output directories for various deployment targets (.output
,.vercel
,.netlify
,.wrangler
,/.svelte-kit
,/build
).
21-26
: Runtime data files
Nicely excludes PID and seed files (pids
,*.pid
,*.seed
,*.pid.lock
).
27-36
: Coverage and instrumentation directories
Ignores instrumented libs (lib-cov
), coverage outputs (coverage
,*.lcov
), and NYC test coverage (.nyc_output
).
37-48
: Task runner and binary addon artifacts
Excludes Grunt storage (.grunt
), Bower dependencies (bower_components
), node-waf files (.lock-wscript
), and compiled addons (build/Release
).
49-55
: Dependency directories
Properly ignoresnode_modules/
,jspm_packages/
, andweb_modules/
.
56-64
: TypeScript and ESLint caches
Covers TypeScript build info (*.tsbuildinfo
) and ESLint cache (.eslintcache
).
65-73
: Microbundle and REPL histories
Ignores microbundle caches (.rpt2_cache/
,.rts2_cache_*
) and REPL history (.node_repl_history
).
74-79
: Archive and integrity files
Excludes npm pack tarballs (*.tgz
) and Yarn integrity file (.yarn-integrity
).
80-83
: Vite timestamp files
Ignores Vite timestamped config backups (vite.config.js.timestamp-*
,vite.config.ts.timestamp-*
).
84-90
: Environment variable files
Covers dotenv variants (.env
,.env.*.local
), ensuring secrets don’t leak.
100-111
: IDE and editor artifacts
Appropriately ignores common IDE/editor files (.idea/
,*.iml
, macOS/Windows artifacts).
120-126
: Secrets and local configs
Good exclusion of sensitive files (secrets.*
,credentials.*
,*.secret
,local.settings.json
).
Signed-off-by: isvladu <[email protected]>
Signed-off-by: isvladu <[email protected]>
# Conflicts: # .gitignore # README.md
…tial-page # Conflicts: # .gitignore
Signed-off-by: isvladu <[email protected]>
1589238
to
fc6546f
Compare
Signed-off-by: Ionut-Sorin Vladu <[email protected]>
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: 7
🧹 Nitpick comments (3)
src/lib/components/Navbar.svelte (3)
7-13
: Consider making navLinks reactive and adding types.The navLinks array would benefit from a type definition and being marked as reactive for better maintainability.
-const navLinks = [ +interface NavLink { + href: string; + label: string; +} + +const navLinks = $state<NavLink[]>([ {href: '/', label: 'Home'}, {href: '/about', label: 'About'}, {href: '/features', label: 'Features'}, {href: '/pricing', label: 'Pricing'}, {href: '/community', label: 'Community'}, -]; +]);
39-41
: Use a dynamic import path for the logo.The current path uses a static reference to favicon.png which might not work in all environments. Consider using a more robust approach.
- <img src="/favicon.png" alt="logo" class="max-h-10 mr-2"> + <img src="{import.meta.env.BASE_URL}/favicon.png" alt="Axonotes logo" class="max-h-10 mr-2"> Axonotes
68-72
: Clean up empty props and improve modal transitions.There are empty string properties in the Modal component that could be removed, and the transitions could be more descriptive.
contentBase="bg-surface-100-900 p-4 space-y-4 shadow-xl w-[80%] max-w-[300px] h-screen" positionerJustify="justify-end" - positionerAlign="" - positionerPadding="" - transitionsPositionerIn={{ x: 400, duration: 200 }} - transitionsPositionerOut={{ x: 400, duration: 200 }} + transitionsPositionerIn={{ x: 400, duration: 200, easing: 'ease-out' }} + transitionsPositionerOut={{ x: 400, duration: 200, easing: 'ease-in' }}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (7)
axonotes-theme.css
(1 hunks)package.json
(1 hunks)src/app.css
(1 hunks)src/app.html
(1 hunks)src/lib/components/LightSwitch.svelte
(1 hunks)src/lib/components/Navbar.svelte
(1 hunks)src/routes/+layout.svelte
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- axonotes-theme.css
🚧 Files skipped from review as they are similar to previous changes (4)
- src/app.css
- src/routes/+layout.svelte
- src/app.html
- package.json
$effect(() => { | ||
const mode = localStorage.getItem('mode') || 'light'; | ||
checked = mode === 'dark'; | ||
}); |
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.
🛠️ Refactor suggestion
Add error handling for localStorage access.
The current implementation assumes localStorage is always available, but it can fail in private browsing mode or when cookies are disabled.
$effect(() => {
- const mode = localStorage.getItem('mode') || 'light';
+ let mode = 'light';
+ try {
+ const storedMode = localStorage.getItem('mode');
+ if (storedMode) {
+ mode = storedMode;
+ }
+ } catch (error) {
+ console.warn('Unable to access localStorage:', error);
+ }
checked = mode === 'dark';
});
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
$effect(() => { | |
const mode = localStorage.getItem('mode') || 'light'; | |
checked = mode === 'dark'; | |
}); | |
$effect(() => { | |
let mode = 'light'; | |
try { | |
const storedMode = localStorage.getItem('mode'); | |
if (storedMode) { | |
mode = storedMode; | |
} | |
} catch (error) { | |
console.warn('Unable to access localStorage:', error); | |
} | |
checked = mode === 'dark'; | |
}); |
🤖 Prompt for AI Agents
In src/lib/components/LightSwitch.svelte around lines 7 to 10, the code accesses
localStorage without error handling, which can cause failures in private
browsing or when cookies are disabled. Wrap the localStorage.getItem call in a
try-catch block to safely handle any exceptions. In the catch block, set a
default mode value to ensure the component continues to function without
crashing.
{#if checked} | ||
<button type="button" class="btn-icon preset-filled scheme-light" onclick={() => onCheckedChange({checked: false})}> | ||
<Sun/> | ||
</button> | ||
{:else} | ||
<button type="button" class="btn-icon preset-filled scheme-dark" onclick={() => onCheckedChange({checked: true})}> | ||
<Moon/> | ||
</button> | ||
{/if} |
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.
🛠️ Refactor suggestion
Improve accessibility and use Svelte's event handling.
The buttons lack proper accessibility attributes, and it's better to use Svelte's on:click directive instead of onclick.
<div class="relative">
{#if checked}
- <button type="button" class="btn-icon preset-filled scheme-light" onclick={() => onCheckedChange({checked: false})}>
+ <button
+ type="button"
+ class="btn-icon preset-filled scheme-light"
+ on:click={() => onCheckedChange({checked: false})}
+ aria-label="Switch to light mode"
+ >
<Sun/>
</button>
{:else}
- <button type="button" class="btn-icon preset-filled scheme-dark" onclick={() => onCheckedChange({checked: true})}>
+ <button
+ type="button"
+ class="btn-icon preset-filled scheme-dark"
+ on:click={() => onCheckedChange({checked: true})}
+ aria-label="Switch to dark mode"
+ >
<Moon/>
</button>
{/if}
</div>
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{#if checked} | |
<button type="button" class="btn-icon preset-filled scheme-light" onclick={() => onCheckedChange({checked: false})}> | |
<Sun/> | |
</button> | |
{:else} | |
<button type="button" class="btn-icon preset-filled scheme-dark" onclick={() => onCheckedChange({checked: true})}> | |
<Moon/> | |
</button> | |
{/if} | |
<div class="relative"> | |
{#if checked} | |
<button | |
type="button" | |
class="btn-icon preset-filled scheme-light" | |
on:click={() => onCheckedChange({checked: false})} | |
aria-label="Switch to light mode" | |
> | |
<Sun/> | |
</button> | |
{:else} | |
<button | |
type="button" | |
class="btn-icon preset-filled scheme-dark" | |
on:click={() => onCheckedChange({checked: true})} | |
aria-label="Switch to dark mode" | |
> | |
<Moon/> | |
</button> | |
{/if} | |
</div> |
🤖 Prompt for AI Agents
In src/lib/components/LightSwitch.svelte around lines 28 to 36, the buttons lack
accessibility attributes like aria-pressed to indicate their state, and the
event handlers use the native onclick attribute instead of Svelte's on:click
directive. To fix this, add appropriate accessibility attributes such as
aria-pressed reflecting the checked state to each button, and replace onclick
with on:click for event handling following Svelte conventions.
src/lib/components/Navbar.svelte
Outdated
<button class="btn" onclick={closeMobileMenu}> | ||
<X/> | ||
</button> |
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.
🛠️ Refactor suggestion
Use Svelte's event handling and add accessibility attributes.
Replace the onclick attribute with Svelte's on:click directive and add aria attributes for better accessibility.
-<button class="btn" onclick={closeMobileMenu}>
+<button
+ class="btn"
+ on:click={closeMobileMenu}
+ aria-label="Close mobile menu"
+>
<X/>
</button>
🤖 Prompt for AI Agents
In src/lib/components/Navbar.svelte around lines 80 to 82, replace the HTML
onclick attribute with Svelte's on:click directive for event handling.
Additionally, add appropriate aria attributes such as aria-label to the button
element to improve accessibility, ensuring screen readers can identify the
button's purpose.
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 (1)
src/routes/+error.svelte (1)
60-66
: Nice touch with the home link – consider prefetchingMinor UX win: add
sveltekit:prefetch
to the anchor so the home page is warmed in the background.-<a href="/" class="btn …"> +<a href="/" sveltekit:prefetch class="btn …">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
static/page-not-found.png
is excluded by!**/*.png
📒 Files selected for processing (1)
src/routes/+error.svelte
(1 hunks)
Signed-off-by: Ionut-Sorin Vladu <[email protected]>
- updated server.js to use ts - updated robots.txt - formatted code
Feat/crawlers
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: 1
🧹 Nitpick comments (2)
src/routes/sitemap.xml/+server.ts (2)
24-30
: Fine-tune priority and change-freq
A blanket priority0.7
/1.0
and fixedweekly
change frequency may mislead crawlers. At minimum, expose helpers so each route can opt-in to custom values (e.g., features page vs. legal pages).Not blocking, but worth revisiting.
43-47
: Includepublic
inCache-Control
header
Without thepublic
directive, some intermediary caches might ignore the header.-"Cache-Control": `max-age=0, s-maxage=${60 * 60 * 24}`, +"Cache-Control": `public, max-age=0, s-maxage=${60 * 60 * 24}`,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/app.d.ts
(1 hunks)src/routes/+error.svelte
(1 hunks)src/routes/sitemap.xml/+server.ts
(1 hunks)static/robots.txt
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- static/robots.txt
🚧 Files skipped from review as they are similar to previous changes (2)
- src/routes/+error.svelte
- src/app.d.ts
🔇 Additional comments (2)
src/routes/sitemap.xml/+server.ts (2)
13-21
: Path normalisation is brittle
The triplereplace()
chain silently fails if any import path deviates (e.g. nestedindex/+page.svelte
, back-slashes on Windows, or a possible future+page.ts
). Usingnew URL
orpath.posix
utilities is safer.-import "/src/routes", "" -.replace("/+page.svelte", "") -.replace(/\/$/, "") +const route = p + .replace(/^.*\/src\/routes/, "") + .replace(/\/\+page\.svelte$/, "") + .replace(/\/index$/, "")
1-1
: Import path is correct – good job
Using the generated route types keeps the handler strongly typed.
src/routes/sitemap.xml/+server.ts
Outdated
// Use Vite's glob import to find all +page.svelte files | ||
// The type for import.meta.glob is generally { [key: string]: () => Promise<unknown> } | ||
const pages: Record<string, () => Promise<unknown>> = import.meta.glob( | ||
"/src/routes/**/+page.svelte" | ||
); |
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.
🛠️ Refactor suggestion
Avoid per-request import.meta.glob
– hoist it and exclude dynamic routes
import.meta.glob()
is resolved at build time, but the expression is still executed every time the endpoint is hit, incurring unnecessary work.
Two additional issues:
- It also matches dynamic segments like
[slug]
, resulting in bogus<loc>
entries (/blog/[slug]
). - Windows builds will emit back-slashes, breaking the replacement logic.
Consider hoisting and filtering once at module scope:
-export const GET: RequestHandler = async ({ setHeaders, url }) => {
- const pages: Record<string, () => Promise<unknown>> =
- import.meta.glob("/src/routes/**/+page.svelte");
+const allPages = Object.keys(
+ import.meta.glob("/src/routes/**/+page.svelte", { eager: false })
+)
+ // strip dynamic parameters
+ .filter((p) => !/\[[^\]]+\]/.test(p));
+
+export const GET: RequestHandler = async ({ setHeaders, url }) => {
This removes the per-request overhead and keeps dynamic placeholders out of the sitemap.
🤖 Prompt for AI Agents
In src/routes/sitemap.xml/+server.ts around lines 7 to 11, the import.meta.glob
call is inside the request handler, causing it to run on every request and
include dynamic routes with placeholders like [slug], which should be excluded.
Move the import.meta.glob call to the module scope (outside the handler) to run
it once at build time, then filter out any paths containing dynamic segments
such as brackets. Also, normalize paths to use forward slashes to avoid issues
on Windows. This will prevent unnecessary work per request and exclude invalid
sitemap entries.
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: 0
🧹 Nitpick comments (2)
README.md (2)
98-100
: Suggest adding polite phrasing to Contributing bullets
For consistency with the “Please open an issue” tone, consider adding “Please” to the Design Ideas bullet.Proposed diff:
- - 🎨 **Design Ideas?** Open an issue to discuss your suggestions. We're keen to make the site as user-friendly and appealing as possible. + - 🎨 **Design Ideas?** Please open an issue to discuss your suggestions. We're keen to make the site as user-friendly and appealing as possible.
105-105
: Suggest polite wording for commit instruction
Consider changing “Make sure” to “Please make sure” for a more courteous tone.Proposed diff:
- 4. Commit your changes (`git commit -m 'Add some amazing feature'`). **_Make sure to sign your commits with gpg!_** + 4. Commit your changes (`git commit -m 'Add some amazing feature'`). **_Please make sure to sign your commits with gpg!_**
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
README.md
(3 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[style] ~100-~100: Consider using polite language here.
Context: ... help users understand Axonotes better, let us know via an issue. - 🛠️ **Code Contribution...
(INSERT_PLEASE)
🔇 Additional comments (5)
README.md (5)
38-45
: Approve core feature list formatting
The new list entries under “We’re building an all-in-one academic suite focused on:” are clear, concise, and consistently formatted.
55-58
: Approve purpose bullet list formatting
The repository purpose bullets are well-structured and use consistent markdown list syntax.
62-62
: Approve star history badge simplification
Replacing the complex<picture>
block with a single markdown badge link improves readability and maintainability.
68-69
: Approve tech stack list formatting
The Tech Stack section is clearly presented with consistent bullet markers and emphasis.
112-113
: Approve feedback channels formatting
The “Share Your Thoughts” and “Quick Survey” bullets are well-formatted and clear.
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: 0
🧹 Nitpick comments (5)
README.md (5)
54-58
: Verify Consistent List Formatting in “About This Website” Section
This block also uses dashes for list items. Ensure all list sections follow the same bullet convention for a cohesive look.
68-70
: Consistent Tech Stack Bullets
These entries are clear. Optionally, you could addtarget="_blank"
to external links for better UX in documentation.
98-100
: Add Politeness to Community Call-to-Action
Consider adding “please” to soften the tone (e.g., “Please let us know via an issue.”) for a more inviting style.
105-105
: Commit Signing Reminder Styling
The italic GPG reminder is effective. You might also consider using a callout block (e.g., a> **Note:**
) for consistency with other admonitions.
120-125
: Review Social Links Section
All social URLs are listed clearly. Confirm that each link points to the official account and consider adding icons for quicker recognition.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
README.md
(3 hunks)src/routes/about/+page.svelte
(1 hunks)src/routes/pricing/+page.svelte
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/routes/pricing/+page.svelte
- src/routes/about/+page.svelte
🧰 Additional context used
🪛 LanguageTool
README.md
[style] ~100-~100: Consider using polite language here.
Context: ... help users understand Axonotes better, let us know via an issue. - 🛠️ **Code Contribution...
(INSERT_PLEASE)
🔇 Additional comments (3)
README.md (3)
38-45
: Inconsistent Summary vs Actual Bullet Style
The AI summary mentioned switching to plus-sign bullets, but this section still uses dashes (-
). Please align the list style across the README or update the summary to reflect the chosen format.Likely an incorrect or invalid review comment.
62-62
: Approve Simplified Star History Badge
Switching to a single markdown badge is concise and clear—great simplification.
109-110
: Validate Contact Methods
The email and survey URLs look correct. Please verify that these endpoints are active and monitored before release.
Feat/initial page multilang
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: 4
♻️ Duplicate comments (7)
src/lib/components/Navbar.svelte (1)
116-116
: Replace onclick with Svelte's on:click directive.The component still uses HTML onclick attributes instead of Svelte's event handling, which was flagged in previous reviews.
- onclick={closeMobileMenu} + on:click={closeMobileMenu}Apply this change to all three instances: lines 116, 131, and 157.
Also applies to: 131-131, 157-157
src/routes/community/+page.svelte (1)
90-92
: Fix the Svelte event handler syntax.The
onclick
attribute is not valid in Svelte. Use theon:click
directive instead.Apply this diff to fix the event handler:
-<button onclick={() => (heartClicked = true)} class={heartClicked ? "cursor-default" : ""}> +<button on:click={() => (heartClicked = true)} class={heartClicked ? "cursor-default" : ""}>src/routes/+page.svelte (3)
468-476
: Add descriptive aria-label for final CTA.The final Discord link should include an aria-label for improved screen reader support.
Apply this diff:
<a href="https://discord.gg/myBMaaDeQu" target="_blank" rel="noopener noreferrer" class="btn preset-filled-secondary-500 inline-flex min-h-[44px] items-center justify-center gap-2 px-4 text-sm text-white sm:px-6 sm:text-base" + aria-label="Join Axonotes waitlist on Discord" > {m.home_finalCta_button()} <ExternalLink class="h-3 w-3 sm:h-4 sm:w-4" /> </a>
95-107
: Enhance accessibility for primary CTA button.The Discord link button lacks proper accessibility attributes and could benefit from better semantic markup.
Apply this diff to improve accessibility:
<a href="https://discord.gg/myBMaaDeQu" target="_blank" rel="noopener noreferrer" class="btn preset-filled-primary-500 inline-flex min-h-[44px] items-center justify-center gap-2 px-4 text-sm text-white sm:px-6 sm:text-base" + aria-label="Join Axonotes Discord community waitlist" > <MessageCircle class="h-4 w-4 sm:h-5 sm:w-5" /> <span class="xs:inline hidden" >{m.home_hero_cta_primary()}</span > {m.home_hero_cta_primary_mobile()} <ArrowRight class="h-3 w-3 sm:h-4 sm:w-4" /> </a>
228-249
: Improve accessibility for core value cards.The value cards need better keyboard navigation and semantic structure for screen readers.
Apply this pattern to enhance accessibility:
{#each coreValues as value (value.title)} {@const Icon = value.icon} - <div class="card p-4 text-center sm:p-6"> + <div + class="card p-4 text-center sm:p-6" + role="article" + aria-labelledby="value-{value.title.toLowerCase().replace(/\s+/g, '-')}" + tabindex="0" + > <div class="bg-primary-100 dark:bg-primary-900/30 mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-lg sm:mb-4 sm:h-12 sm:w-12" > <Icon class="text-primary-600 dark:text-primary-400 h-5 w-5 sm:h-6 sm:w-6" + aria-hidden="true" /> </div> <h3 + id="value-{value.title.toLowerCase().replace(/\s+/g, '-')}" class="text-surface-900 dark:text-surface-100 mb-2 text-sm font-semibold sm:text-base" > {value.title} </h3>src/routes/about/+page.svelte (2)
437-440
: Fix Svelte event handler syntax for heart button.The
onclick
attribute is not valid in Svelte. Use theon:click
directive instead.Apply this diff to fix the event handler:
<button - onclick={() => (heartClicked = true)} + on:click={() => (heartClicked = true)} class={heartClicked ? "cursor-default" : ""} >
474-482
: Remove target="_blank" for internal navigation.The community link points to an internal page but uses
target="_blank"
, which will unnecessarily open a new tab and confuse users.Apply this diff to fix the internal navigation:
<a href="/community" - target="_blank" - rel="noopener noreferrer" class="btn preset-filled-primary-500 inline-flex items-center justify-center gap-2 px-4 py-2 text-sm text-white md:px-6 md:py-3 md:text-base" > <Users class="h-4 w-4" /> {m.about_cta_button1()} </a>
🧹 Nitpick comments (3)
src/app.html (2)
2-6
: Hard-codeddata-theme
limits runtime theme switchingYou later toggle colour themes client-side, but this static attribute locks the root to
"axonotes-theme"
.
Consider reading the user-preferred theme fromlocalStorage
(orprefers-color-scheme
) in a tiny inline script and updating the attribute before first paint to prevent FOUC.
7-12
: Add basic SEO / PWA meta tags while the template is freshBeyond title & viewport, include:
+ <meta name="description" content="Axonotes – your neuroscience note-taking companion" /> + <link rel="manifest" href="%sveltekit.assets%/site.webmanifest" /> + <meta name="theme-color" content="#101010" media="(prefers-color-scheme: dark)" />Those small additions improve search discoverability and PWA install experience.
src/lib/components/LanguageSwitcher.svelte (1)
23-67
: Consider enhancing keyboard navigation and focus management.The popover implementation is solid but could benefit from improved keyboard navigation within the language list and proper focus management when opening/closing.
Consider adding:
- Arrow key navigation between language options
- Focus management to return focus to trigger after selection
- Enhanced ARIA labels for better screen reader support
+ import { tick } from 'svelte'; + + let popoverContent: HTMLElement; + + async function handleLanguageSelect(event: Event) { + closePopover(); + await tick(); + // Return focus to trigger button + (event.target as HTMLElement)?.closest('[data-trigger]')?.focus(); + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (24)
.github/workflows/ninja_i18n.yml
(1 hunks)messages/de.json
(1 hunks)messages/en.json
(1 hunks)package.json
(1 hunks)project.inlang/.gitignore
(1 hunks)project.inlang/project_id
(1 hunks)project.inlang/settings.json
(1 hunks)src/app.d.ts
(1 hunks)src/app.html
(1 hunks)src/hooks.server.ts
(1 hunks)src/hooks.ts
(1 hunks)src/lib/components/LanguageSwitcher.svelte
(1 hunks)src/lib/components/Navbar.svelte
(1 hunks)src/lib/components/SelfHostingSection.svelte
(1 hunks)src/lib/i18n.ts
(1 hunks)src/routes/+error.svelte
(1 hunks)src/routes/+layout.svelte
(1 hunks)src/routes/+page.svelte
(1 hunks)src/routes/about/+page.svelte
(1 hunks)src/routes/community/+page.svelte
(1 hunks)src/routes/features/+page.server.ts
(1 hunks)src/routes/features/+page.svelte
(1 hunks)src/routes/pricing/+page.svelte
(1 hunks)vite.config.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (9)
- project.inlang/.gitignore
- src/hooks.ts
- project.inlang/project_id
- src/lib/i18n.ts
- project.inlang/settings.json
- .github/workflows/ninja_i18n.yml
- messages/de.json
- messages/en.json
- src/lib/components/SelfHostingSection.svelte
🚧 Files skipped from review as they are similar to previous changes (6)
- src/routes/+error.svelte
- src/routes/pricing/+page.svelte
- src/routes/features/+page.svelte
- src/routes/+layout.svelte
- src/routes/features/+page.server.ts
- package.json
🧰 Additional context used
🧠 Learnings (5)
src/app.d.ts (3)
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In SvelteKit 2.12+ with Svelte 5, the page object is imported from `$app/state` (not the deprecated `$app/stores`) and accessed directly without the `$` prefix. So use `import { page } from "$app/state"` and then `page.status`, `page.error`, `page.url.pathname` etc. directly. The old `$app/stores` with `$page.status` syntax is deprecated. The migration guide specifically says to remove the `$` prefix when accessing variables in templates.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:1-5
Timestamp: 2025-06-17T20:47:26.756Z
Learning: In Svelte 5 with SvelteKit 2.12+, use `import { page } from "$app/state"` instead of `import { page } from "$app/stores"`. The page object from $app/state is a reactive state object that doesn't require the `$` prefix for dereferencing (e.g., `page.status`, `page.data`, `page.error?.message`). The `$app/stores` module is deprecated in newer SvelteKit versions.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In Svelte 5, the `page` object is imported from `$app/state` (not `$app/stores` like in Svelte 4) and can be accessed directly as `page.status`, `page.error`, etc. without the `$` prefix. The reactive `$` syntax is not needed when using Svelte 5's state system.
src/routes/community/+page.svelte (4)
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In Svelte 5, the `page` object is imported from `$app/state` (not `$app/stores` like in Svelte 4) and can be accessed directly as `page.status`, `page.error`, etc. without the `$` prefix. The reactive `$` syntax is not needed when using Svelte 5's state system.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:1-5
Timestamp: 2025-06-17T20:47:26.756Z
Learning: In Svelte 5 with SvelteKit 2.12+, use `import { page } from "$app/state"` instead of `import { page } from "$app/stores"`. The page object from $app/state is a reactive state object that doesn't require the `$` prefix for dereferencing (e.g., `page.status`, `page.data`, `page.error?.message`). The `$app/stores` module is deprecated in newer SvelteKit versions.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In SvelteKit 2.12+ with Svelte 5, the page object is imported from `$app/state` (not the deprecated `$app/stores`) and accessed directly without the `$` prefix. So use `import { page } from "$app/state"` and then `page.status`, `page.error`, `page.url.pathname` etc. directly. The old `$app/stores` with `$page.status` syntax is deprecated. The migration guide specifically says to remove the `$` prefix when accessing variables in templates.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In Svelte 5 with the new runes system, the `page` object should be imported from `$app/state` and accessed directly as `page.status`, `page.error`, etc. without the `$` prefix. This is different from earlier versions where you'd import from `$app/stores` and use `$page.status`. The direct access pattern without `$` is correct for Svelte 5's state system.
src/routes/+page.svelte (4)
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In Svelte 5, the `page` object is imported from `$app/state` (not `$app/stores` like in Svelte 4) and can be accessed directly as `page.status`, `page.error`, etc. without the `$` prefix. The reactive `$` syntax is not needed when using Svelte 5's state system.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In SvelteKit 2.12+ with Svelte 5, the page object is imported from `$app/state` (not the deprecated `$app/stores`) and accessed directly without the `$` prefix. So use `import { page } from "$app/state"` and then `page.status`, `page.error`, `page.url.pathname` etc. directly. The old `$app/stores` with `$page.status` syntax is deprecated. The migration guide specifically says to remove the `$` prefix when accessing variables in templates.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In Svelte 5 with the new runes system, the `page` object should be imported from `$app/state` and accessed directly as `page.status`, `page.error`, etc. without the `$` prefix. This is different from earlier versions where you'd import from `$app/stores` and use `$page.status`. The direct access pattern without `$` is correct for Svelte 5's state system.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:1-5
Timestamp: 2025-06-17T20:47:26.756Z
Learning: In Svelte 5 with SvelteKit 2.12+, use `import { page } from "$app/state"` instead of `import { page } from "$app/stores"`. The page object from $app/state is a reactive state object that doesn't require the `$` prefix for dereferencing (e.g., `page.status`, `page.data`, `page.error?.message`). The `$app/stores` module is deprecated in newer SvelteKit versions.
src/routes/about/+page.svelte (4)
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In Svelte 5, the `page` object is imported from `$app/state` (not `$app/stores` like in Svelte 4) and can be accessed directly as `page.status`, `page.error`, etc. without the `$` prefix. The reactive `$` syntax is not needed when using Svelte 5's state system.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:1-5
Timestamp: 2025-06-17T20:47:26.756Z
Learning: In Svelte 5 with SvelteKit 2.12+, use `import { page } from "$app/state"` instead of `import { page } from "$app/stores"`. The page object from $app/state is a reactive state object that doesn't require the `$` prefix for dereferencing (e.g., `page.status`, `page.data`, `page.error?.message`). The `$app/stores` module is deprecated in newer SvelteKit versions.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In SvelteKit 2.12+ with Svelte 5, the page object is imported from `$app/state` (not the deprecated `$app/stores`) and accessed directly without the `$` prefix. So use `import { page } from "$app/state"` and then `page.status`, `page.error`, `page.url.pathname` etc. directly. The old `$app/stores` with `$page.status` syntax is deprecated. The migration guide specifically says to remove the `$` prefix when accessing variables in templates.
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In Svelte 5 with the new runes system, the `page` object should be imported from `$app/state` and accessed directly as `page.status`, `page.error`, etc. without the `$` prefix. This is different from earlier versions where you'd import from `$app/stores` and use `$page.status`. The direct access pattern without `$` is correct for Svelte 5's state system.
src/app.html (1)
Learnt from: ImGajeed76
PR: axonotes/AxonotesHomepage#1
File: src/routes/+error.svelte:7-18
Timestamp: 2025-06-17T20:48:00.743Z
Learning: In SvelteKit 2.12+ with Svelte 5, the page object is imported from `$app/state` (not the deprecated `$app/stores`) and accessed directly without the `$` prefix. So use `import { page } from "$app/state"` and then `page.status`, `page.error`, `page.url.pathname` etc. directly. The old `$app/stores` with `$page.status` syntax is deprecated. The migration guide specifically says to remove the `$` prefix when accessing variables in templates.
🧬 Code Graph Analysis (1)
src/hooks.server.ts (1)
src/lib/i18n.ts (1)
i18n
(5-5)
🪛 Biome (1.9.4)
src/app.d.ts
[error] 22-23: This empty export is useless because there's another export or import.
This import makes useless the empty export.
Safe fix: Remove this useless empty export.
(lint/complexity/noUselessEmptyExport)
🪛 HTMLHint (1.5.0)
src/app.html
[error] 12-12: <title> must be present in tag.
(title-require)
🔇 Additional comments (8)
src/lib/components/LanguageSwitcher.svelte (1)
46-46
: Verify i18n.route API before mergingI wasn’t able to locate the
i18n.route
definition in the repo—please confirm that it accepts both a pathname and a target-language argument (e.g.route(pathname, lang)
) before you apply the suggested diff:- href={i18n.route(page.url.pathname)} + href={i18n.route(page.url.pathname, lang)}Ensure that any consumer of
i18n.route
is updated accordingly and that existing routes continue to resolve correctly.src/lib/components/Navbar.svelte (1)
1-26
: LGTM - Clean component structure.The script setup is well-organized with proper imports, localized navigation links, and clean state management using Svelte 5 patterns.
src/hooks.server.ts (1)
1-6
: LGTM - Proper i18n server hook setup.The server hook correctly integrates the Paraglide i18n handler using SvelteKit's sequence utility. This follows the standard pattern for internationalization setup.
vite.config.ts (2)
12-14
: Consider security implications of allowedHosts configuration.The preview configuration allows all subdomains of
.axonotes.ch
. Ensure this aligns with your deployment and security requirements.Verify that this host configuration is intended for your deployment setup and doesn't expose the development server unnecessarily.
1-15
: LGTM - Well-configured Vite setup.The plugin configuration correctly integrates Paraglide for i18n, Tailwind CSS for styling, and SvelteKit. The plugin order is appropriate and the Paraglide configuration matches the project structure.
src/app.d.ts (3)
23-23
: Empty export is necessary for module declaration.The static analysis tool flagged this as useless, but the empty export statement is actually required in TypeScript to treat this file as a module when it only contains
declare
statements.The Biome linter is incorrect in this case - removing the empty export would cause TypeScript compilation issues.
1-21
: LGTM - Proper TypeScript declarations for i18n integration.The type declarations correctly extend the App.Locals interface with Paraglide types and provide proper typing for the internationalization setup. The import paths and type usage align with the project's i18n infrastructure.
17-21
: Good module declaration for .svx files.The module declaration properly types
.svx
files as Svelte components, which supports the markdown-based content components used in the project.
<button | ||
onclick={() => (coffeeClicked = true)} | ||
class={coffeeClicked ? "cursor-default" : ""} | ||
> | ||
<Coffee | ||
class="text-primary-500 h-5 w-5 {coffeeClicked | ||
? 'animate-bounce' | ||
: 'hover:scale-110'} transition-all duration-200 md:h-6 md:w-6" | ||
aria-hidden="true" | ||
/> | ||
</button> |
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.
🛠️ Refactor suggestion
Enhance accessibility for interactive coffee button.
The coffee button needs proper accessibility attributes for screen readers and keyboard users.
Apply this diff to improve accessibility:
<button
on:click={() => (coffeeClicked = true)}
class={coffeeClicked ? "cursor-default" : ""}
+ aria-label={coffeeClicked ? "Development status animation activated" : "Click to animate development status"}
+ aria-pressed={coffeeClicked}
+ disabled={coffeeClicked}
>
<Coffee
class="text-primary-500 h-5 w-5 {coffeeClicked
? 'animate-bounce'
: 'hover:scale-110'} transition-all duration-200 md:h-6 md:w-6"
aria-hidden="true"
/>
</button>
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/routes/about/+page.svelte around lines 320 to 330, the coffee button
lacks accessibility attributes. Add an aria-label describing the button's
purpose, ensure the button is focusable and operable via keyboard by using
standard button element behavior, and consider adding role or aria-pressed
attributes if the button toggles state. This will improve screen reader and
keyboard user experience.
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: 0
♻️ Duplicate comments (1)
src/app.html (1)
7-11
: Add a mandatory<title>
element for spec-compliance and SEOThe
<head>
block still omits a<title>
tag, which is required by the HTML specification and flagged by HTMLHint. Search-engine crawlers and accessibility tools rely on it.<meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> + + <!-- Document title (static fallback; dynamic titles are appended via %sveltekit.head%) --> + <title>Axonotes</title>
🧹 Nitpick comments (1)
src/app.html (1)
32-43
: Consider distinct theme-color values for light vs dark schemesBoth
prefers-color-scheme
meta tags use#6089f7
. If the dark theme background is substantially darker, that hue may clash with browser UI elements (e.g., Android address bar). Providing a darker variant (or omitting the dark entry to let the user-agent derive it) yields a more polished appearance.- <meta - name="theme-color" - content="#6089f7" - media="(prefers-color-scheme: dark)" - /> + <meta + name="theme-color" + content="#2743af" <!-- example darker shade --> + media="(prefers-color-scheme: dark)" + />
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (6)
static/apple-touch-icon.png
is excluded by!**/*.png
static/favicon-96x96.png
is excluded by!**/*.png
static/favicon.ico
is excluded by!**/*.ico
static/favicon.svg
is excluded by!**/*.svg
static/web-app-manifest-192x192.png
is excluded by!**/*.png
static/web-app-manifest-512x512.png
is excluded by!**/*.png
📒 Files selected for processing (5)
src/app.html
(1 hunks)src/lib/components/Navbar.svelte
(1 hunks)src/lib/components/SelfHostingSection.svelte
(1 hunks)src/routes/+layout.svelte
(1 hunks)static/site.webmanifest
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- static/site.webmanifest
🚧 Files skipped from review as they are similar to previous changes (3)
- src/lib/components/Navbar.svelte
- src/lib/components/SelfHostingSection.svelte
- src/routes/+layout.svelte
🧰 Additional context used
🪛 HTMLHint (1.5.0)
src/app.html
[error] 58-58: <title> must be present in tag.
(title-require)
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: 0
♻️ Duplicate comments (1)
src/app.html (1)
55-58
: Add a<title>
fallback before%sveltekit.head%
The document still lacks a
<title>
element, which violates the HTML spec and hampers SEO. The previous review already highlighted this; please address it or explicitly justify why dynamic titles alone are sufficient. A minimal, localised fallback keeps validators quiet and covers error pages where no dynamic head is rendered.<meta name="referrer" content="strict-origin-when-cross-origin" /> + <!-- Fallback title (overridden by %sveltekit.head% when present) --> + <title>Axonotes</title> + %sveltekit.head%
🧹 Nitpick comments (1)
src/app.html (1)
30-45
: Consider adding a meta description for basic SEOA short, meaningful
meta name="description"
improves search-engine snippets and link previews.<link rel="manifest" href="%sveltekit.assets%/site.webmanifest" /> + <!-- SEO --> + <meta + name="description" + content="Axonotes – the next-generation note-taking companion for neuroscience students and professionals." + /> + <!-- Theme and colors -->
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app.html
(1 hunks)
🧰 Additional context used
🪛 HTMLHint (1.5.0)
src/app.html
[error] 58-58: <title> must be present in tag.
(title-require)
PR TODO: Axonotes Website - Initial Structure & Content
This PR aims to set up the foundational pages and content outline for the Axonotes website.
Key Pages & Sections to Implement/Review:
Summary by CodeRabbit
New Features
Documentation
Chores
Style