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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/solid-sample/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Logto Solid Sample</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./src/index.tsx"></script>
</body>
</html>
22 changes: 22 additions & 0 deletions packages/solid-sample/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@logto/solid-sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "vite"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@logto/solid": "workspace:^",
"solid-js": "^1.9.5",
"@solidjs/router": "^0.15.3"
},
"devDependencies": {
"typescript": "^5.3.3",
"vite": "^6.0.9",
"vite-plugin-solid": "^2.11.2"
}
}
Binary file added packages/solid-sample/public/favicon.ico
Binary file not shown.
34 changes: 34 additions & 0 deletions packages/solid-sample/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { LogtoProvider, type LogtoConfig, UserScope } from "@logto/solid";
import { type RouteDefinition, Router } from "@solidjs/router";
import {lazy} from "solid-js";

import "./app.css";
import { appId, endpoint } from './consts';

const routes: RouteDefinition[] = [
{ path: '/', component: lazy(() => import("./pages/Home")) },
{ path: '/callback', component: lazy(() => import("./pages/Callback")) },
{ path: '/protected', component: lazy(() => import("./pages/ProtectedResource")) },
{ path: '/protected/organizations', component: lazy(() => import("./pages/Organizations")) },
];

export function App() {
const config: LogtoConfig = {
appId,
endpoint,
scopes: [
UserScope.Email,
UserScope.Phone,
UserScope.CustomData,
UserScope.Identities,
UserScope.Organizations,
],
};
return (
<LogtoProvider config={config}>
<div class="flex flex-col min-h-screen">
<Router>{routes}</Router>
</div>
</LogtoProvider>
);
}
4 changes: 4 additions & 0 deletions packages/solid-sample/src/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
body {
margin: 0;
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
}
7 changes: 7 additions & 0 deletions packages/solid-sample/src/consts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const baseUrl = window.location.origin;
export const redirectUrl = `${baseUrl}/callback`;

export const appId = 'hi9w1eijf2nlnuz88xjt6'; // Register the sample app in Logto dashboard
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can replace them with env variables.

Copy link
Member

@charIeszhao charIeszhao Apr 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or just consts with fake ID, like in the other samples. Not a big deal, though.

export const endpoint = 'http://localhost:3001'; // Replace with your own Logto endpoint
// export const resource = "your-resource-identifier"; // Replace with your own API resource identifier
export const resource = ""; // Replace with your own API resource identifier
7 changes: 7 additions & 0 deletions packages/solid-sample/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { render } from "solid-js/web";
import { App } from "./App";

const root = document.getElementById("app");
if (root) {
render(() => <App />, root);
}
15 changes: 15 additions & 0 deletions packages/solid-sample/src/pages/Callback.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useHandleSignInCallback } from '@logto/solid';
import { useNavigate } from '@solidjs/router';
import { Show } from 'solid-js';

export default function Callback() {
const navigate = useNavigate();
const { isLoading } = useHandleSignInCallback(() => {
console.log("???")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to replace with more friendly message or delete it.

navigate('/');
});

return <Show when={isLoading()}>
<p>Redirecting...</p>
</Show>
};
77 changes: 77 additions & 0 deletions packages/solid-sample/src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useLogto, type UserInfoResponse } from '@logto/solid';
import { createSignal, Show } from "solid-js";
import { baseUrl, redirectUrl } from '../consts';

const Home = () => {
const {isAuthenticated, signIn, signOut, fetchUserInfo} = useLogto();
const [user, setUser] = createSignal<UserInfoResponse>();

(async () => {
if (isAuthenticated()) {
const userInfo = await fetchUserInfo();
setUser(userInfo);
}
})();

return (
<div>
<h3>Logto Solid sample</h3>
<Show when={!isAuthenticated()}>
<button
type="button"
onClick={() => {
void signIn(redirectUrl);
}}
>
Sign in
</button>
<button
type="button"
onClick={() => {
void signIn(redirectUrl, 'signUp');
}}
>
Sign up
</button>
</Show>
<Show when={isAuthenticated()}>
<button
type="button"
onClick={() => {
void signOut(baseUrl);
}}
>
Sign out
</button>
</Show>
<Show when={isAuthenticated() && user()}>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{Object.entries(user()).map(([key, value]) => (
<tr>
<td>{key}</td>
<td>{typeof value === 'string' ? value : JSON.stringify(value)}</td>
</tr>
))}
</tbody>
</table>
<ul>
<li>
<a href="/protected">View protected resource</a>
</li>
<li>
<a href="/protected/organizations">View organizations</a>
</li>
</ul>
</Show>
</div>
);
};

export default Home;
44 changes: 44 additions & 0 deletions packages/solid-sample/src/pages/Organizations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useLogto } from '@logto/solid';
import { createSignal, onMount } from 'solid-js';

const Organizations = () => {
const { getOrganizationToken, getOrganizationTokenClaims, getIdTokenClaims } = useLogto();
const [organizationIds, setOrganizationIds] = createSignal<string[]>();

onMount(() => {
(async () => {
const claims = await getIdTokenClaims();

console.log('ID token claims', claims);
setOrganizationIds(claims?.organizations);
})();
});

return (
<section>
<h2>Organizations</h2>
<a href="/">Go back</a>
{organizationIds()?.length === 0 && <p>No organization memberships found.</p>}
<ul>
{organizationIds()?.map((organizationId) => {
return (
<li style={{ display: 'flex', 'align-items': 'center', gap: '8' }}>
<span>{organizationId}</span>
<button
type="button"
onClick={async () => {
console.log('raw token', await getOrganizationToken(organizationId));
console.log('claims', await getOrganizationTokenClaims(organizationId));
}}
>
fetch token (see console)
</button>
</li>
);
})}
</ul>
</section>
);
};

export default Organizations;
27 changes: 27 additions & 0 deletions packages/solid-sample/src/pages/ProtectedResource.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useLogto } from "@logto/solid";
import { createSignal, Show } from "solid-js";
import { resource } from "../consts";

const ProtectedResource = () => {
const { isAuthenticated, isLoading, signIn, getAccessToken } = useLogto();
const [accessToken, setAccessToken] = createSignal<string>();
const handleClick = async () => {
const token = await getAccessToken(resource);
setAccessToken(token);
};
return (
<section>
<a href="/">Go back</a>
<Show when={isAuthenticated()}>
<p>Protected resource is only visible after sign-in.</p>
</Show>
<button type="button" onClick={handleClick}>Get access token</button>
<Show when={accessToken()}>
Access token: <code>{accessToken()}</code>
</Show>
</section>
)
;
};

export default ProtectedResource;
26 changes: 26 additions & 0 deletions packages/solid-sample/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "esnext",
"esModuleInterop": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"jsx": "preserve",
"jsxImportSource": "solid-js",
"strict": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"skipLibCheck": true,
"noEmit": false,
"outDir": "lib",
"types": ["solid-js"]
},
"include": [
"src",
"vitest.config.ts"
]
}
25 changes: 25 additions & 0 deletions packages/solid-sample/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { fileURLToPath, URL } from "url";

import { defineConfig } from "vite";
import solid from "vite-plugin-solid";

// https://vitejs.dev/config/
export default defineConfig({
plugins: [solid()],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
optimizeDeps: {
include: ["@logto/solid"],
},
build: {
// commonjsOptions: {
// include: [/vue/, /node_modules/],
// },
},
server: {
port: 3000,
},
});
46 changes: 46 additions & 0 deletions packages/solid/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@logto/solid",
"version": "0.0.0",
"type": "module",
"module": "./dist/esm/index.js",
"types": "./dist/types/index.d.ts",
"exports": {
"types": "./dist/types/index.d.ts",
"import": "./dist/esm/index.js",
"default": "./dist/source/index.js"
},
"files": [
"dist"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/logto-io/js.git",
"directory": "packages/solid"
},
"scripts": {
"dev:tsc": "tsc -p tsconfig.build.json -w --preserveWatchOutput",
"precommit": "lint-staged",
"check": "tsc --noEmit",
"build": "rm -rf lib/ && tsc -p tsconfig.build.json --noEmit && rollup -c",
"lint": "eslint --ext .ts --ext .tsx src",
"test": "vitest",
"test:coverage": "vitest --silent --coverage",
"prepack": "pnpm build && pnpm test"
},
"dependencies": {
"@logto/browser": "workspace:^",
"@silverhand/essentials": "^2.9.2",
"solid-js": "^1.9.5"
},
"devDependencies": {
"rollup-preset-solid": "^3.0.0",
"typescript": "^5.3.3"
},
"peerDependencies": {
"solid-js": ">=1.9.0"
},
"publishConfig": {
"access": "public"
}
}
7 changes: 7 additions & 0 deletions packages/solid/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import withSolid from "rollup-preset-solid";

export default withSolid({
input: "src/index.ts",
targets: ["esm"],
});

Loading
Loading