docs: add a playground example per operation in the perms recipe

One runnable example for each section: request a folder, request the
email address, request apps or subdomains, and check before prompting.
This commit is contained in:
Juan Castro authored and GitHub committed 2026-09-29 23:58:53 +07:00
1 parent ad526ea89b
commit 2bad853445
5 files changed
+108

No files matched your search

+24
View File
@@ -945,6 +945,30 @@ const examples = [
slug: 'perms-request-permission',
source: '/playground/examples/perms-request-permission.html',
},
{
title: 'Recipe: ask for a folder',
description: 'Ask the user for write access to Documents and save a file with Puter.js permissions API. Run and experiment with this example in the playground.',
slug: 'perms-ask-for-access-folder',
source: '/playground/examples/perms-ask-for-access-folder.html',
},
{
title: 'Recipe: ask for the email address',
description: "Ask the user for their email address with Puter.js permissions API. Run and modify this example instantly in your browser.",
slug: 'perms-ask-for-access-email',
source: '/playground/examples/perms-ask-for-access-email.html',
},
{
title: 'Recipe: ask about apps or subdomains',
description: 'Ask for read or write access to the user apps and subdomains with Puter.js permissions API. Run and experiment with this example in the playground.',
slug: 'perms-ask-for-access-apps',
source: '/playground/examples/perms-ask-for-access-apps.html',
},
{
title: 'Recipe: check before you prompt',
description: 'Check whether access is already held before showing an opt-in with Puter.js permissions API. Run and modify this example directly in your browser.',
slug: 'perms-ask-for-access-check',
source: '/playground/examples/perms-ask-for-access-check.html',
},
],
},
{
@@ -0,0 +1,20 @@
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<button id="apps">Read my apps</button>
<button id="subdomains">Publish subdomains</button>
<script>
// These two resolve to a plain boolean, unlike 'folder' and 'email'.
document.getElementById('apps').addEventListener('click', async () => {
const granted = await puter.perms.request('apps');
puter.print(granted ? 'Can read apps' : 'Declined');
});
document.getElementById('subdomains').addEventListener('click', async () => {
// access defaults to 'read'; 'write' covers reading too.
const granted = await puter.perms.request('subdomains', { access: 'write' });
puter.print(granted ? 'Can manage subdomains' : 'Declined');
});
</script>
</body>
</html>
@@ -0,0 +1,27 @@
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<button id="go">Save to Documents</button>
<script>
const details = { name: 'Documents', access: 'write' };
(async () => {
// check() never prompts, so it can decide what the UI offers.
const held = await puter.perms.check('folder', details);
document.getElementById('go').textContent = held
? 'Save to Documents'
: 'Allow access, then save';
})();
document.getElementById('go').addEventListener('click', async () => {
const path = await puter.perms.request('folder', details);
if (!path) {
puter.print('Access declined');
return;
}
await puter.fs.write(`${path}/notes.txt`, 'Saved!');
puter.print('Saved');
});
</script>
</body>
</html>
@@ -0,0 +1,14 @@
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<button id="go">Show my email address</button>
<script>
document.getElementById('go').addEventListener('click', async () => {
// Resolves to the address itself, not a boolean.
const email = await puter.perms.request('email');
puter.print(email ? email : 'Declined');
});
</script>
</body>
</html>
@@ -0,0 +1,23 @@
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<button id="go">Save a note to Documents</button>
<script>
document.getElementById('go').addEventListener('click', async () => {
// Resolves to the folder's path, or undefined when declined.
const path = await puter.perms.request('folder', {
name: 'Documents',
access: 'write',
});
if (!path) {
puter.print('Access declined');
return;
}
await puter.fs.write(`${path}/notes.txt`, 'Saved!');
puter.print(`Wrote to ${path}/notes.txt`);
});
</script>
</body>
</html>