71 | ```
72 |
73 | ## echo() vs Logging
74 |
75 | - **echo()**: Immediate response output
76 |
77 | ```ejs
78 | <%% echo(data) %>
79 | ```
80 |
81 | - **dbg(), info()**: Server-side logging
82 | ```ejs
83 | <%% dbg(data) %>
84 | ```
85 |
86 | ## Important Notes
87 |
88 | - In loaders, `echo()` writes to the response stream before headers are sent
89 | - In templates, `echo()` writes inline with the template output
90 | - No need to use `<%%= %>` - just `<%% echo() %>` is sufficient
91 | - Multiple arguments are automatically space-separated
92 | - Objects are automatically stringified
93 |
94 | ## See Also
95 |
96 | - [Logging Functions](/docs/global-api/log)
97 | - [Global API](/docs/global-api)
98 | - [Context API Documentation](/docs/context-api)
99 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/context-api/meta.md:
--------------------------------------------------------------------------------
1 | # `meta` - Managing Page Metadata and Global Values
2 |
3 | - **Type**: Function
4 | - **Description**: The `meta` function provides a way to get and set metadata and other global values during request processing. While it can be used for any global values, it's most commonly used to manage page metadata like titles, descriptions, and OpenGraph tags.
5 |
6 | ## Function Signature:
7 |
8 | ```typescript
9 | meta(key: string): string | undefined
10 | meta(key: string, value: string): string
11 | ```
12 |
13 | ## Usage Patterns:
14 |
15 | 1. **Getting a value**:
16 |
17 | ```ejs
18 | <%% const pageTitle = meta('title'); %>
19 | ```
20 |
21 | 2. **Setting a value**:
22 |
23 | ```ejs
24 | <%% meta('title', 'Welcome to My Site'); %>
25 | ```
26 |
27 | ## Common Use Cases:
28 |
29 | The most common use case for `meta` is setting page metadata in your `+load.js` files and then using those values in your layout templates. Here's a typical example from a layout file:
30 |
31 | ```ejs
32 |
33 | <%%= meta('title') || 'PocketPages' %>
34 |
35 |
39 |
40 |
41 |
42 |
46 |
50 |
54 |
55 | ```
56 |
57 | ## Setting Metadata in Load Files:
58 |
59 | You can set metadata values in your `+load.js` files before the page renders:
60 |
61 | ```js
62 | export default async ({ meta }) => {
63 | meta('title', 'About Us')
64 | meta('description', 'Learn more about our company and mission')
65 | meta('image', 'https://example.com/about-preview.jpg')
66 |
67 | return {
68 | // ... other loaded data
69 | }
70 | }
71 | ```
72 |
73 | ## Additional Use Cases:
74 |
75 | While metadata is the primary use case, `meta` can be used for any global values that need to be accessed across different parts of your application during a request:
76 |
77 | ```ejs
78 | <%%
79 | // Set a global theme
80 | meta('theme', 'dark');
81 |
82 | // Set the current user's preferred language
83 | meta('language', 'en-US');
84 |
85 | // Later, access these values anywhere in your templates
86 | const theme = meta('theme');
87 | const language = meta('language');
88 | %>
89 | ```
90 |
91 | > **Note**: Values set using `meta` only persist for the duration of the current request. They do not persist across different requests or between different users.
92 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/context-api/params.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: params - Route Parameters
3 | description: Access URL route parameters in PocketPages templates using the params object.
4 | ---
5 |
6 | # `params` - Route Parameters
7 |
8 | - **Type**: Object
9 | - **Description**: The `params` object contains routing parameters derived from placeholder directory and file names (parts of the path wrapped in square brackets). For query string parameters, you'll need to parse them manually from `request.url`.
10 |
11 | ## Route Parameters
12 |
13 | Route parameters are defined using square brackets in file and directory names. For example:
14 |
15 | ```
16 | pb_hooks/
17 | pages/
18 | products/
19 | [category]/ # params.category
20 | [id].ejs # params.id
21 | users/
22 | [userId]/
23 | posts/
24 | [postId].ejs # Both params.userId and params.postId available
25 | ```
26 |
27 | ## Example Usage
28 |
29 | ### Basic Parameter Access
30 |
31 | ```ejs
32 |
33 |
76 |
77 |
78 |
79 | ```
80 |
81 | ## Important Notes
82 |
83 | 1. `params` only contains route parameters (from square brackets in paths)
84 | 2. Query string parameters are not directly supported - you'll need to parse them manually from `request.url`
85 | 3. All parameter values are strings
86 | 4. Route parameters are required - if a route parameter is missing, the page won't match
87 |
88 | For query string parameters, you can parse them manually from the request URL:
89 |
90 | ```ejs
91 | <%%
92 | // URL: /products/electronics/123?sort=price&order=desc
93 | const url = new URL(request.url)
94 | const sort = url.searchParams.get('sort')
95 | const order = url.searchParams.get('order')
96 | %>
97 | ```
98 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/context-api/request-oauth2-login.md:
--------------------------------------------------------------------------------
1 | # requestOAuth2Login
2 |
3 | Initiates the OAuth2 authentication flow by redirecting to the provider's authorization endpoint.
4 |
5 | ## Usage
6 |
7 | ```javascript
8 | const authUrl = requestOAuth2Login(providerName)
9 | ```
10 |
11 | ## Parameters
12 |
13 | - `providerName` (string) - The name of the OAuth2 provider (e.g. "google", "github")
14 | - `options` (object, optional)
15 | - `collection` (string) - The collection to authenticate against (defaults to "users")
16 | - `redirectPath` (string) - The path to redirect to after authentication (defaults to "/auth/oauth/confirm")
17 | - `cookieName` (string) - The name of the cookie to store OAuth2 state (defaults to "pp_oauth_state")
18 | - `autoRedirect` (boolean) - Whether to automatically redirect to the provider (defaults to true)
19 |
20 | ## Returns
21 |
22 | Returns the authorization URL if `autoRedirect` is false. Otherwise redirects to the provider's authorization endpoint.
23 |
24 | ## Example
25 |
26 | ```javascript
27 |
37 |
38 |
42 | ```
43 |
44 | ## Notes
45 |
46 | - The function automatically generates and stores a state parameter to prevent CSRF attacks
47 | - The state and other OAuth2 parameters are stored in a cookie for validation during callback
48 | - The default redirect URL is constructed using your app's base URL + the redirectPath option
49 | - Make sure the redirect URL matches what is configured in your OAuth2 provider settings
50 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/context-api/sign-in-with-oauth2.md:
--------------------------------------------------------------------------------
1 | # signInWithOAuth2
2 |
3 | Completes the OAuth2 authentication flow by exchanging the authorization code for an access token and user data.
4 |
5 | ## Usage
6 |
7 | ```javascript
8 | const authData = signInWithOAuth2(state, code)
9 | ```
10 |
11 | ## Parameters
12 |
13 | - `state` (string) - The state parameter returned from the OAuth2 provider
14 | - `code` (string) - The authorization code returned from the OAuth2 provider
15 | - `options` (object, optional) - Additional options
16 | - `collection` (string) - The collection to authenticate against (defaults to "users")
17 | - `cookieName` (string) - The name of the cookie storing the OAuth2 state (defaults to "pp_oauth_state")
18 |
19 | ## Returns
20 |
21 | Returns an object containing:
22 |
23 | - `token` - The authentication token
24 | - `record` - The user record
25 |
26 | ## Example
27 |
28 | ```javascript
29 |
39 | ```
40 |
41 | ## Notes
42 |
43 | - This function is typically called on your OAuth2 callback route after the provider redirects back to your application
44 | - The function automatically validates the state parameter against the stored state to prevent CSRF attacks
45 | - On successful authentication, the user is automatically signed in and the auth cookie is set
46 | - Throws an error if the state validation fails or if the OAuth2 flow cannot be completed
47 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/context-api/sign-in-with-token.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: signInWithToken - Token Authentication
3 | description: Set authentication state using a token in PocketPages templates.
4 | ---
5 |
6 | # `signInWithToken` - Token Authentication
7 |
8 | - **Type**: `(token: string) => void`
9 | - **Description**: Core authentication function that sets the `pb_auth` cookie. All other authentication methods (`signInWithPassword`, `registerWithPassword`, `signInAnonymously`) internally use this function to set the cookie.
10 |
11 | ## Basic Usage
12 |
13 | ```ejs
14 | <%%
15 | // Set authentication using a token
16 | signInWithToken('your-auth-token-here')
17 | redirect('/dashboard')
18 | %>
19 | ```
20 |
21 | ## Cookie Management
22 |
23 | This is the only function that directly sets the `pb_auth` cookie. Other authentication methods work like this:
24 |
25 | ```typescript
26 | // How signInWithPassword works internally
27 | function signInWithPassword(email: string, password: string) {
28 | // 1. Authenticate with PocketBase
29 | const authData = pb.collection('users').authWithPassword(...)
30 |
31 | // 2. Use signInWithToken to set the cookie
32 | signInWithToken(authData.token)
33 |
34 | return authData
35 | }
36 | ```
37 |
38 | ## Common Use Cases
39 |
40 | ### OAuth Flow Completion
41 |
42 | ```ejs
43 | <%%
44 | // After receiving token from OAuth provider
45 | const token = params.token
46 | if (token) {
47 | signInWithToken(token)
48 | redirect('/dashboard')
49 | } else {
50 | redirect('/login?error=missing_token')
51 | }
52 | %>
53 | ```
54 |
55 | ### Custom Authentication Flow
56 |
57 | ```ejs
58 | <%%
59 | if (request.method === 'POST') {
60 | try {
61 | // Custom authentication logic
62 | const response = await customAuthProvider.authenticate(formData)
63 |
64 | if (response.token) {
65 | signInWithToken(response.token)
66 | redirect('/dashboard')
67 | }
68 |
69 | } catch (error) {
70 | %>
71 |
74 | <%%
75 | }
76 | }
77 | %>
78 | ```
79 |
80 | ## Important Notes
81 |
82 | 1. **Cookie Management**: This function:
83 |
84 | - Is the core cookie-setting function used by all auth methods
85 | - Sets the `pb_auth` cookie with the provided token
86 | - Does not validate the token
87 | - Does not fetch the user record
88 |
89 | 2. **Security Considerations**:
90 |
91 | - Always validate tokens before using them
92 | - Use HTTPS in production
93 | - Consider token expiration
94 | - Protect against CSRF attacks
95 |
96 | 3. **Usage Context**: Typically used:
97 | - After third-party authentication
98 | - In custom authentication flows
99 | - When implementing token refresh logic
100 | - Internally by other auth methods
101 |
102 | ## Related Topics
103 |
104 | - [`signInWithPassword`](/docs/context-api/sign-in-with-password)
105 | - [`signOut`](/docs/context-api/sign-out)
106 | - [`request.auth`](/docs/context-api/auth)
107 | - [Authentication Guide](/docs/authentication)
108 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/context-api/sign-out.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: signOut - User Logout
3 | description: Sign out the current user by clearing their authentication cookie in PocketPages templates.
4 | ---
5 |
6 | # `signOut` - User Logout
7 |
8 | - **Type**: `() => void`
9 | - **Description**: Signs out the current user by clearing their authentication cookie. After calling this function, `request.auth` will be `undefined` on subsequent requests.
10 |
11 | ## Basic Usage
12 |
13 | ```ejs
14 | <%%
15 | signOut()
16 | redirect('/login')
17 | %>
18 | ```
19 |
20 | ## Common Use Cases
21 |
22 | ### Logout Button/Form
23 |
24 | ```ejs
25 | <%%
26 | if (request.method === 'POST' && formData.action === 'logout') {
27 | signOut()
28 | redirect('/login')
29 | }
30 | %>
31 |
32 |
36 | ```
37 |
38 | ### Session Expiry Handler
39 |
40 | ```ejs
41 | <%%
42 | if (request.auth) {
43 | const lastActivity = new Date(request.auth.get('lastActivity'))
44 | const now = new Date()
45 | const inactiveTime = now - lastActivity
46 |
47 | if (inactiveTime > 30 * 60 * 1000) { // 30 minutes
48 | signOut()
49 | redirect('/login?reason=session_expired')
50 | return
51 | }
52 | }
53 | %>
54 | ```
55 |
56 | ## Important Notes
57 |
58 | 1. **Cookie Management**: This function:
59 |
60 | - Clears the authentication cookie
61 | - Takes effect immediately
62 | - Does not require a server response
63 |
64 | 2. **Security Considerations**:
65 |
66 | - Always redirect after logout
67 | - Clear any client-side state
68 | - Consider implementing CSRF protection
69 | - Use POST requests for logout actions
70 |
71 | 3. **Best Practices**:
72 |
73 | - Redirect to login page after logout
74 | - Show confirmation messages
75 | - Handle errors gracefully
76 | - Consider cleanup of user-specific data
77 |
78 | 4. **Client-Side Integration**:
79 | - This function only clears the server-side cookie
80 | - If using the PocketBase JS SDK on the frontend, you'll need to handle its authentication state separately
81 | - The SDK uses localStorage for JWT storage, which isn't affected by cookie changes
82 | - Consider implementing a complete logout that handles both:
83 |
84 | ```ejs
85 |
86 |
99 |
100 |
101 | ```
102 |
103 | ## Related Topics
104 |
105 | - [`signInWithPassword`](/docs/context-api/sign-in-with-password)
106 | - [`signInWithToken`](/docs/context-api/sign-in-with-token)
107 | - [`request.auth`](/docs/context-api/auth)
108 | - [Authentication Guide](/docs/authentication)
109 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/creating-a-page.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Creating a PocketPages Page
3 | description: Step-by-step process for creating and organizing EJS template files in PocketPages, including file naming conventions, directory structure, and URL routing patterns.
4 | ---
5 |
6 | # Creating a PocketPages Page
7 |
8 | PocketPages allows you to create dynamic pages for your application using EJS templating. Below are the steps and guidelines to create a page that will be served by PocketPages.
9 |
10 | ## Creating Pages
11 |
12 | 1. **Create an EJS File**: Inside the `pb_hooks/pages/` directory, create an `.ejs` file. This file will represent the page that you want to serve.
13 |
14 | For example, to create an "About" page:
15 |
16 | ```text
17 | pb_hooks/pages/about.ejs
18 | ```
19 |
20 | 2. **Special Case - `index.ejs`**: The `index.ejs` file has a special role at any directory level.
21 |
22 | At the root level:
23 |
24 | ```text
25 | pb_hooks/pages/index.ejs -> serves "/"
26 | ```
27 |
28 | In subdirectories:
29 |
30 | ```text
31 | pb_hooks/pages/products/index.ejs -> serves "/products"
32 | ```
33 |
34 | 3. **Serving Pages**: Any `.ejs` file within `pb_hooks/pages/` can be served directly. The name of the file (minus the `.ejs` extension) will correspond to the URL path.
35 |
36 | Example file structure:
37 |
38 | ```text
39 | pb_hooks/pages/
40 | ├── index.ejs -> "/"
41 | ├── about.ejs -> "/about"
42 | ├── contact.ejs -> "/contact"
43 | └── products/
44 | ├── index.ejs -> "/products"
45 | └── details.ejs -> "/products/details"
46 | ```
47 |
48 | 4. **Nested Pages**: You can organize your pages into subdirectories. The routing will follow the directory structure. If no specific file matches the route, an `index.ejs` in the corresponding directory will be served.
49 |
50 | Example routing table:
51 |
52 | ```text
53 | URL Path File Path
54 | / pb_hooks/pages/index.ejs
55 | /about pb_hooks/pages/about.ejs
56 | /contact pb_hooks/pages/contact.ejs
57 | /products pb_hooks/pages/products/index.ejs
58 | /products/details pb_hooks/pages/products/details.ejs
59 | ```
60 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/database.md:
--------------------------------------------------------------------------------
1 | # Server-side Data
2 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/debugging.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Debugging in PocketPages
3 | description: Learn how to enable and configure debugging output in PocketPages applications.
4 | ---
5 |
6 | # Debugging in PocketPages
7 |
8 | PocketPages provides several levels of debugging output to help you develop and troubleshoot your application.
9 |
10 | ## Development Mode
11 |
12 | Running PocketBase with the `--dev` flag automatically enables debug output from the `dbg()` function (see [Logging Functions](/docs/global-api/log) for details):
13 |
14 | ```bash
15 | pocketbase serve --dev
16 | ```
17 |
18 | Without the `--dev` flag, all `dbg()` output is suppressed, making your production logs cleaner and more focused on important information.
19 |
20 | ## Plugin Debugging
21 |
22 | Each plugin can have its own debug output enabled or disabled. By default, plugin debugging is disabled. You can enable it for specific plugins in your `+config.js` file:
23 |
24 | ```javascript
25 | module.exports = {
26 | plugins: [
27 | // Enable debugging for just the EJS plugin
28 | {
29 | name: 'pocketpages-plugin-ejs',
30 | debug: true,
31 | },
32 |
33 | // Other plugins remain quiet
34 | 'pocketpages-plugin-marked',
35 | ],
36 | debug: false,
37 | }
38 | ```
39 |
40 | See [Configuration](/docs/config) for more details about plugin configuration.
41 |
42 | ## Core Debugging
43 |
44 | PocketPages core debugging is disabled by default. While rarely needed, you can enable it by setting the top-level `debug` option in your `+config.js`:
45 |
46 | ```javascript
47 | module.exports = {
48 | plugins: ['pocketpages-plugin-ejs'],
49 | debug: true, // Enable core debugging
50 | }
51 | ```
52 |
53 | This will output detailed information about routes, parameters, and other internal details that can be helpful when troubleshooting core PocketPages behavior.
54 |
55 | > **Note**: Enabling core debugging can produce a lot of output. It's recommended to only enable it when specifically debugging PocketPages core functionality.
56 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/deploying.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Deploying to Production
3 | description: Deploy PocketPages to pockethost.io with manual or GitHub Actions workflows, or self-host on Fly.io. Includes deployment scripts, environment setup, and configuration steps.
4 | ---
5 |
6 | # Deploying to Production
7 |
8 | PocketPages is easy to deploy. If you follow the [recommended project structure](/docs/structure), everything in `/pb_*` can be deployed.
9 |
10 | The two most popular ways to go live with PocketBase are to use [pockethost.io](https://pockethost.io) or to self-host using [Fly.io](https://fly.io).
11 |
12 | ## Recommended: Deploy to pockethost.io
13 |
14 | pockethost.io is the premiere PocketBase hosting service trusted by over 10,000 developers and millions of end users.
15 |
16 | In under 30 seconds, you can provision a free instance with unlimited (Fair Use) resources.
17 |
18 | ### Manual Deployment
19 |
20 | The easiest way to deploy is using the PocketHost.IO CLI utility (PHIO). Here's how:
21 |
22 | 1. Install the PHIO CLI globally:
23 |
24 | ```bash
25 | npm i -g phio
26 | ```
27 |
28 | 2. Login to your PocketHost account:
29 |
30 | ```bash
31 | phio login
32 | ```
33 |
34 | 3. Link your local project to your PocketHost instance:
35 |
36 | ```bash
37 | phio link
38 | ```
39 |
40 | 4. Deploy your project:
41 |
42 | ```bash
43 | phio deploy
44 | ```
45 |
46 | ### Github Actions Deployment
47 |
48 | To set up automated deployments using Github Actions:
49 |
50 | ```bash
51 | cp -r node_modules/pocketpages/starters/deploy-pockethost-ga .
52 | ```
53 |
54 | You'll need to set a few Github secrets. Look in the YAML file for details.
55 |
56 | ## Deploy to Fly.io
57 |
58 | _Warning: Self-hosting is an advanced setup. I know Fly pretty well and it still took me an hour._
59 |
60 | To set up Fly.io deployment:
61 |
62 | ```bash
63 | cp -r node_modules/pocketpages/starters/deploy-fly-ga .
64 | ```
65 |
66 | After this, you should see a `Dockerfile` and `fly.toml`.
67 |
68 | Use `fly launch` and `fly deploy` to create a Fly app and deploy it.
69 |
70 | For more information, see [Host for Free on Fly.io](https://github.com/pocketbase/pocketbase/discussions/537)
71 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/directory-structure.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Directory Structure
3 | description: File organization requirements and conventions for PocketPages applications, including the mandatory pb_hooks/pages/ root directory and examples of nested page structures.
4 | ---
5 |
6 | # Directory Structure
7 |
8 | All PocketPages must reside within the `pb_hooks/pages/` directory of your project. This is the designated location where PocketPages looks for pages to serve.
9 |
10 | ### Example Structure:
11 |
12 | ```
13 | pb_hooks/
14 | pages/
15 | index.ejs
16 | about.ejs
17 | contact.ejs
18 | products/
19 | index.ejs
20 | details.ejs
21 | ```
22 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/features.md:
--------------------------------------------------------------------------------
1 | # Key Features
2 |
3 | PocketPages is a modern web framework built on PocketBase that combines the simplicity of file-based routing with the power of server-side rendering. It's designed to help developers build fast, secure, and SEO-friendly web applications with minimal configuration. Whether you're building a simple landing page or a complex web application, PocketPages provides the tools and features you need while maintaining a lightweight footprint.
4 |
5 | ## Fast and Lightweight
6 |
7 | - Built on Golang and Goja for high performance
8 | - Minimal dependencies and small footprint
9 | - Quick startup times and efficient resource usage
10 |
11 | ## Powered by PocketBase
12 |
13 | - Full access to PocketBase JSVM API
14 | - Native database integration
15 | - Built-in authentication and authorization
16 | - Real-time capabilities
17 |
18 | ## Modern Development Experience
19 |
20 | - File-based routing for intuitive navigation
21 | - EJS templating for dynamic content
22 | - Built-in asset management with fingerprinting
23 | - Hot reloading in development
24 | - TypeScript support
25 |
26 | ## Server-Side Rendering
27 |
28 | - SEO-friendly by default
29 | - Fast initial page loads
30 | - Reduced client-side JavaScript
31 | - Support for meta tags and OpenGraph
32 |
33 | ## Robust Features
34 |
35 | - Global proxy network support
36 | - Content-based cache invalidation
37 | - Private file handling
38 | - Form processing
39 | - Middleware support
40 | - Markdown processing
41 | - Environment variable management
42 |
43 | ## Developer Tools
44 |
45 | - VSCode/Cursor integration
46 | - Built-in debugging helpers
47 | - Comprehensive type definitions
48 | - Clear error messages
49 |
50 | ## Framework Integration
51 |
52 | - HTMX support for dynamic updates
53 | - AlpineJS for client-side interactivity
54 | - TailwindCSS + DaisyUI for styling
55 | - Markdown with code highlighting
56 |
57 | ## Deployment Options
58 |
59 | - One-click deploy to pockethost.io
60 | - Self-hosting support on Fly.io
61 | - GitHub Actions integration
62 | - Custom domain configuration
63 | - Environment-based configuration
64 |
65 | ## Security Features
66 |
67 | - Secure by default
68 | - Private directory protection
69 | - Environment variable management
70 | - Form validation helpers
71 | - CSRF protection
72 |
73 | ## Performance
74 |
75 | - Automatic asset fingerprinting
76 | - Efficient caching strategies
77 | - CDN-friendly architecture
78 | - Response compression
79 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/global-api/env.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: env - Environment Variable Access
3 | description: Securely access environment variables in PocketPages applications
4 | ---
5 |
6 | # `env` - Environment Variable Access
7 |
8 | - **Type**: `(key: string) => string`
9 | - **Description**: The `env` function provides secure access to environment variables. It returns an empty string if the variable is not found.
10 |
11 | ## Basic Usage
12 |
13 | ```javascript
14 | const apiKey = env('API_KEY')
15 | const dbPassword = env('DB_PASSWORD')
16 | ```
17 |
18 | ## Template Usage
19 |
20 | ```ejs
21 | <%% const apiKey = env('API_KEY') %>
22 |
Using API key: <%%= apiKey %>
23 | ```
24 |
25 | ## Security Notes
26 |
27 | - Returns empty string for undefined variables
28 | - Use for sensitive configuration
29 | - Avoid exposing secrets in templates
30 | - Prefer environment variables over hardcoded values
31 |
32 | ## Best Practices
33 |
34 | 1. **Check for Required Variables**
35 |
36 | ```javascript
37 | const apiKey = env('API_KEY')
38 | if (!apiKey) {
39 | error('Missing required API_KEY environment variable')
40 | // Handle error case
41 | }
42 | ```
43 |
44 | 2. **Use Descriptive Names**
45 |
46 | ```javascript
47 | // Good
48 | const stripeSecretKey = env('STRIPE_SECRET_KEY')
49 |
50 | // Avoid
51 | const key = env('KEY')
52 | ```
53 |
54 | 3. **Document Required Variables**
55 |
56 | ```javascript
57 | // Document required environment variables in your README or configuration files
58 | /**
59 | * Required environment variables:
60 | * - API_KEY: Your API key for external service
61 | * - DB_PASSWORD: Database password
62 | * - SMTP_PASSWORD: Email service password
63 | */
64 | ```
65 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/global-api/micro-dash.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Micro-dash Functions
3 | description: Lightweight utility functions for working with arrays and objects
4 | ---
5 |
6 | # Micro-dash Functions
7 |
8 | PocketPages includes a subset of utility functions from [@s-libs/micro-dash](https://github.com/simontonsoftware/s-libs/tree/master/projects/micro-dash) for working with arrays and objects. These functions are available globally in templates and via `require('pocketpages')`.
9 |
10 | ## Available Functions
11 |
12 | ### forEach
13 |
14 | Iterates over elements of a collection and invokes an iteratee for each element.
15 |
16 | ```js
17 | const { forEach } = require('pocketpages')
18 |
19 | forEach([1, 2, 3], (value) => {
20 | dbg(value)
21 | })
22 |
23 | forEach({ a: 1, b: 2 }, (value, key) => {
24 | dbg(key, value)
25 | })
26 | ```
27 |
28 | ### keys
29 |
30 | Gets the object's property names as an array.
31 |
32 | ```js
33 | const { keys } = require('pocketpages')
34 |
35 | const obj = { a: 1, b: 2, c: 3 }
36 | const propertyNames = keys(obj)
37 | // => ['a', 'b', 'c']
38 | ```
39 |
40 | ### values
41 |
42 | Gets the object's property values as an array.
43 |
44 | ```js
45 | const { values } = require('pocketpages')
46 |
47 | const obj = { a: 1, b: 2, c: 3 }
48 | const propertyValues = values(obj)
49 | // => [1, 2, 3]
50 | ```
51 |
52 | ### merge
53 |
54 | Recursively merges own enumerable properties of source objects into the destination object.
55 |
56 | ```js
57 | const { merge } = require('pocketpages')
58 |
59 | const object = {
60 | a: [{ b: 2 }, { d: 4 }],
61 | }
62 |
63 | const other = {
64 | a: [{ c: 3 }, { e: 5 }],
65 | }
66 |
67 | merge(object, other)
68 | // => { a: [{ b: 2, c: 3 }, { d: 4, e: 5 }] }
69 | ```
70 |
71 | ### pick
72 |
73 | Creates an object composed of the picked object properties.
74 |
75 | ```js
76 | const { pick } = require('pocketpages')
77 |
78 | const object = { a: 1, b: 2, c: 3, d: 4 }
79 | pick(object, ['a', 'c'])
80 | // => { a: 1, c: 3 }
81 | ```
82 |
83 | ## Using in Templates
84 |
85 | These functions are automatically available in EJS templates:
86 |
87 | ```ejs
88 | <%%
89 | forEach(['Home', 'About', 'Contact'], (page) => {
90 | echo(`${page}`)
91 | })
92 | %>
93 |
94 | <%%
95 | const config = { theme: 'dark', lang: 'en' }
96 | const userPrefs = { theme: 'light' }
97 | const finalConfig = merge({}, config, userPrefs)
98 | %>
99 | ```
100 |
101 | ## Using in JavaScript Files
102 |
103 | Import the functions you need from the PocketPages package:
104 |
105 | ```js
106 | const { forEach, keys, values, merge, pick } = require('pocketpages')
107 |
108 | function processObject(obj) {
109 | forEach(keys(obj), (key) => {
110 | dbg(`Processing ${key}:`, obj[key])
111 | })
112 | }
113 | ```
114 |
115 | For more detailed information about these utility functions, refer to the [@s-libs/micro-dash documentation](https://github.com/simontonsoftware/s-libs/tree/master/projects/micro-dash).
116 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/global-api/stringify.md:
--------------------------------------------------------------------------------
1 | # `stringify` - Circular-Safe Stringify Helper
2 |
3 | - **Type**: Function
4 | - **Description**: The `stringify` helper is a `JSON.stringify` replacement that prevents circular references from causing errors. It is useful when you need to serialize complex objects for logging or debugging.
5 |
6 | ## Example Usage:
7 |
8 | ```ejs
9 | <%% log.dbg("Request Context:", stringify(context)); %>
10 | ```
11 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/global-api/url.md:
--------------------------------------------------------------------------------
1 | # `url` - URL Parsing Function
2 |
3 | - **Type**: Function
4 | - **Description**: The `url` function is used to parse a URL string. It returns an object equivalent to using `new URL()` in the browser's Web API, with the addition of automatic query string parsing into an object. This can be helpful for manipulating or inspecting URLs within your EJS templates.
5 |
6 | ## Example Usage:
7 |
8 | ```ejs
9 | <%%
10 | // Basic URL parsing
11 | const parsedUrl = url('https://example.com/path?query=123');
12 | %>
13 |
Hostname: <%%= parsedUrl.hostname %>
14 |
Pathname: <%%= parsedUrl.pathname %>
15 |
Search: <%%= parsedUrl.search %>
16 |
17 | <%%
18 | // Query string parsing
19 | const withQuery = url('https://example.com/search?name=john&age=25&tags[]=one&tags[]=two')
20 |
21 | // Query parameters are automatically parsed into an object
22 | dbg({
23 | name: withQuery.query.name, // "john"
24 | age: withQuery.query.age, // "25"
25 | tags: withQuery.query.tags // ["one", "two"]
26 | })
27 | %>
28 | ```
29 |
30 | ## Query String Parsing
31 |
32 | The `query` property contains an object with all query parameters parsed:
33 |
34 | - Simple parameters become string values
35 | - Array parameters (using `[]`) become arrays
36 | - Empty values become empty strings
37 | - Missing values become `undefined`
38 |
39 | ```ejs
40 | <%%
41 | const examples = [
42 | url('/?name=alice'), // query.name === "alice"
43 | url('/?items[]=1&items[]=2'), // query.items === ["1", "2"]
44 | url('/?empty='), // query.empty === ""
45 | url('/?missing'), // query.missing === undefined
46 | url('/?a=1&b=2&c=3') // query === { a: "1", b: "2", c: "3" }
47 | ]
48 | %>
49 | ```
50 |
51 | ## See Also
52 |
53 | - [Request Context](/docs/context-api/request)
54 | - [Redirect](/docs/context-api/redirect)
55 | - [Parameters](/docs/parameters)
56 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/index.md:
--------------------------------------------------------------------------------
1 | <%- include('overview.md') %>
2 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Installation
3 | description: Step-by-step guide for installing PocketPages.
4 | ---
5 |
6 | # Installation
7 |
8 | > **PocketPages requires PocketBase v0.25.5 or later.**
9 |
10 | Installing PocketPages is easy.
11 |
12 | <%- include(`quickstart.ejs`) %>
13 |
14 | _Note: `--dir=pb_data` is necessary to tell PocketBase to use the current directory for data storage._
15 |
16 | Browse to `http://localhost:8090` and with any luck at all, you'll see:
17 |
18 | <%- include(`browser.ejs`, { url: `http://localhost:8090`, content: `Hello, world!`}) %>
19 |
20 | To start editing, find
21 |
22 | ```
23 | ./pb_hooks/pages/index.ejs
24 | ```
25 |
26 | Changes appear immediately on the next refresh.
27 |
28 | ## How does it work?
29 |
30 | PocketPages is a Multi-Page Application (MPA) preprocessor for PocketBase. It listens for requests and renders pages using file-based routing rules like old school PHP.
31 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/jsvm.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: JavaScript API
3 | description: PocketBase's JavaScript runtime environment capabilities, limitations, and examples for database operations, with details on NPM package compatibility and available APIs.
4 | ---
5 |
6 | # JavaScript API
7 |
8 | PocketBase's JavaScript runtime environment is neither Browser nor NodeJS. As such, it lacks Web APIs and NodeJS APIs such as `Buffer` and `require('fs')`.
9 |
10 | There is [extensive documentation](https://pocketbase.io/docs/js-overview/) covering many aspects of extending PocketBase with JS hooks. You'll probably be most concerned with [database operations](https://pocketbase.io/docs/js-database/) and higher-level [record operations](https://pocketbase.io/docs/js-records/), like this:
11 |
12 | ```js
13 | const records = $app.findRecordsByExpr(
14 | 'articles',
15 | $dbx.exp('LOWER(username) = {:username}', { username: 'John.Doe' }),
16 | $dbx.hashExp({ status: 'pending' })
17 | )
18 | ```
19 |
20 | Going even deeper, look at the [PocketBase JSVM docs](https://pocketbase.io/jsvm/index.html) to see available APIs. It's a little hard to understand, so hopefully the examples we provide will help to fill in any unfamiliar concepts.
21 |
22 | ## But can I use my favorite NPM package?
23 |
24 | Probably not, but maybe you're luckier than I am. Any NPM modules that work as pure EcmaScript will also work inside PocketBase, as long as they are CommonJS.
25 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/markdown.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Markdown Support
3 | description: PocketPages processes .md files through EJS templating and Markdown parsing, with built-in frontmatter support for metadata extraction via the meta() function in templates.
4 | ---
5 |
6 | # Markdown Support in PocketPages
7 |
8 | PocketPages supports rendering `.md` files, treating them similarly to `.ejs` files but with an additional step: Markdown parsing.
9 |
10 | ## How It Works:
11 |
12 | 1. **EJS Processing**: Any file with the `.md` extension is first processed through the EJS engine, just like a regular `.ejs` file. This means you can use all the dynamic templating features of EJS within your Markdown files.
13 |
14 | 2. **Markdown Parsing**: After EJS processing, the content is passed through a Markdown parser. This ensures that any Markdown syntax (such as headers, lists, and links) is properly rendered into HTML.
15 |
16 | 3. **Final Output**: The last step in the pipeline is Markdown parsing, so the final output is HTML content that reflects both your EJS logic and your Markdown formatting.
17 |
18 | ## Frontmatter Support
19 |
20 | Any frontmatter properties defined at the top of your Markdown file will be automatically available through the request context's `meta` function. For example:
21 |
22 | ```markdown
23 | ---
24 | title: My Blog Post
25 | description: A detailed guide about something interesting
26 | author: John Doe
27 | ---
28 |
29 | # Content starts here...
30 | ```
31 |
32 | You can then access these values in your layouts or other templates using the `meta` function:
33 |
34 | ```ejs
35 | <%%= meta('title') %>
36 |
37 |
38 | ```
39 |
40 | ## Important Notes:
41 |
42 | - **Layouts Cannot Be Markdown**: While `.md` files can include dynamic content through EJS and Markdown, they cannot be used as layouts. Layouts must be `.ejs` files.
43 |
44 | By supporting Markdown in this way, PocketPages allows you to combine the power of dynamic EJS templates with the simplicity and readability of Markdown, making it easier to manage content-heavy projects.
45 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/overview.md:
--------------------------------------------------------------------------------
1 | <%- include('overview.md') %>
2 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/parameters.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Route and Query Parameters'
3 | description: 'Access URL path segments and query strings in PocketPages templates using params.paramName. Route parameters use [brackets] in file/directory names. Query parameters override route parameters when names conflict.'
4 | ---
5 |
6 | # Route and Query Parameters
7 |
8 | PocketPages lets you access both route parameters (from URL paths) and query parameters (from query strings) in your templates.
9 |
10 | ## Route Parameters
11 |
12 | Use square brackets `[]` in file or directory names to capture URL path segments as parameters.
13 |
14 | ### Example Structure
15 |
16 | ```
17 | pb_hooks/pages/
18 | products/
19 | [productId]/
20 | index.ejs
21 | [productId]/reviews/
22 | [reviewId].ejs
23 | ```
24 |
25 | This structure handles URLs like:
26 |
27 | - `/products/123`
28 | - `/products/123/reviews/456`
29 |
30 | ### Using Route Parameters
31 |
32 | Access route parameters through `params` in your templates:
33 |
34 | ```ejs
35 |
36 |
Product: <%%= params.productId %>
37 |
38 |
39 |
Product: <%%= params.productId %>
40 |
Review: <%%= params.reviewId %>
41 | ```
42 |
43 | ## Query Parameters
44 |
45 | Query parameters come from the URL's query string (after the `?`). They're also available through `params`:
46 |
47 | ```
48 | /products/123?sort=latest&highlight=true
49 | ```
50 |
51 | Access them the same way in templates:
52 |
53 | ```ejs
54 |
Sort by: <%%= params.sort %>
55 |
Highlight: <%%= params.highlight %>
56 | ```
57 |
58 | ## Parameter Priority
59 |
60 | Query parameters override route parameters when they have the same name:
61 |
62 | ```
63 | /products/123?productId=789
64 | ```
65 |
66 | Here, `params.productId` will be `789`, not `123`.
67 |
68 | ## Complete Example
69 |
70 | URL:
71 |
72 | ```
73 | /products/123/reviews/456?sort=latest&highlight=true
74 | ```
75 |
76 | Template:
77 |
78 | ```ejs
79 |
Product: <%%= params.productId %>
80 |
Review: <%%= params.reviewId %>
81 |
Sort by: <%%= params.sort %>
82 |
Highlight: <%%= params.highlight %>
83 | ```
84 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/plugins/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Plugins
3 | description: Extend PocketPages with custom functionality using its powerful plugin architecture.
4 | ---
5 |
6 | # Plugins
7 |
8 | PocketPages has a highly **flexible plugin architecture** that allows you to extend the framework far beyond templating. Plugins can interact with various stages of your application, from request and response handling to rendering and extending the API context.
9 |
10 | ## Official Plugins
11 |
12 | PocketPages comes with several official plugins:
13 |
14 | - **EJS Plugin**: Template processing with enhanced features
15 | - **Markdown Plugin**: Process Markdown files with frontmatter support
16 | - **Realtime Plugin**: Add Server-Sent Events (SSE) support
17 | - **Authentication Plugin**: Complete auth system with multiple methods
18 | - **JS SDK Plugin**: PocketBase JavaScript SDK integration
19 | - **Micro Dash Plugin**: Lightweight utility functions for data manipulation
20 |
21 | ## What Can Plugins Do?
22 |
23 | - **Extend Request and Response:**
24 | Use hooks such as `onRequest` and `onResponse` to modify request processing and response delivery.
25 | - **Customize Rendering:**
26 | Intercept and modify output with the `onRender` hook.
27 | - **Extend the API:**
28 | Add custom functions or even integrate entire sub-applications via `onExtendContextApi`.
29 |
30 | ## Plugin Processing Order
31 |
32 | Plugins are processed in the order they appear in your `plugins` array. This is particularly important when plugins modify content, as each plugin's output becomes the input for the next plugin.
33 |
34 | For example, when using both EJS and Markdown plugins:
35 |
36 | ```javascript
37 | module.exports = {
38 | plugins: [
39 | // First: Process EJS templates
40 | 'pocketpages-plugin-ejs',
41 | // Second: Convert Markdown to HTML
42 | 'pocketpages-plugin-marked',
43 | ],
44 | }
45 | ```
46 |
47 | This sequential processing allows you to:
48 |
49 | - Chain transformations
50 | - Extend functionality incrementally
51 | - Control how content is processed
52 |
53 | Consider the processing order when configuring plugins that work together or modify the same types of content.
54 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/plugins/micro-dash.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Micro Dash Plugin
3 | description: Lightweight utility functions for data manipulation in PocketPages applications.
4 | ---
5 |
6 | # Micro Dash Plugin
7 |
8 | The Micro Dash plugin (`pocketpages-plugin-micro-dash`) provides a set of lightweight utility functions for data manipulation, based on the `@s-libs/micro-dash` library.
9 |
10 | ## Installation
11 |
12 | ```bash
13 | npm install pocketpages-plugin-micro-dash
14 | ```
15 |
16 | ## Configuration
17 |
18 | Add the plugin to your `+config.js` file:
19 |
20 | ```javascript
21 | module.exports = {
22 | plugins: [
23 | 'pocketpages-plugin-micro-dash',
24 | // ... other plugins
25 | ],
26 | }
27 | ```
28 |
29 | ## Available Functions
30 |
31 | The plugin adds several utility functions to the global context:
32 |
33 | ```typescript
34 | // Collection Operations
35 | function forEach(
36 | collection: T[],
37 | iteratee: (value: T, key: number) => void
38 | ): void
39 | function keys(object: object): string[]
40 | function values(object: { [key: string]: T }): T[]
41 |
42 | // Object Operations
43 | function merge(...objects: object[]): object
44 | function pick(object: T, ...props: string[]): Partial
45 |
46 | // Array Operations
47 | function shuffle(array: T[]): T[]
48 | ```
49 |
50 | ## Usage Examples
51 |
52 | ### Collection Operations
53 |
54 | ```ejs
55 | <%%
56 | // Iterate over arrays or objects
57 | forEach([1, 2, 3], (value) => {
58 | echo(value)
59 | })
60 |
61 | // Get object keys
62 | const obj = { a: 1, b: 2 }
63 | const objKeys = keys(obj) // ['a', 'b']
64 |
65 | // Get object values
66 | const objValues = values(obj) // [1, 2]
67 | %>
68 | ```
69 |
70 | ### Object Operations
71 |
72 | ```ejs
73 | <%%
74 | // Merge objects
75 | const merged = merge(
76 | { a: 1 },
77 | { b: 2 },
78 | { c: 3 }
79 | ) // { a: 1, b: 2, c: 3 }
80 |
81 | // Pick specific properties
82 | const user = {
83 | id: 1,
84 | name: 'John',
85 | email: 'john@example.com',
86 | password: 'secret'
87 | }
88 | const safeUser = pick(user, 'id', 'name', 'email')
89 | %>
90 | ```
91 |
92 | ### Array Operations
93 |
94 | ```ejs
95 | <%%
96 | // Shuffle an array
97 | const numbers = [1, 2, 3, 4, 5]
98 | const shuffled = shuffle(numbers)
99 | %>
100 | ```
101 |
102 | ## Performance
103 |
104 | The micro-dash functions are optimized for size and performance, making them ideal for server-side use in the JSVM environment. They provide a subset of Lodash functionality without the full library overhead.
105 |
106 | ## Type Safety
107 |
108 | All functions are fully typed and provide TypeScript support out of the box:
109 |
110 | ```typescript
111 | interface User {
112 | id: number
113 | name: string
114 | email: string
115 | }
116 |
117 | // Types are preserved
118 | const users: User[] = [
119 | /*...*/
120 | ]
121 | forEach(users, (user: User) => {
122 | // user is properly typed
123 | })
124 |
125 | const userObj: User = {
126 | /*...*/
127 | }
128 | const partial = pick(userObj, 'id', 'name')
129 | // partial is Partial>
130 | ```
131 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/prettier.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Prettier Configuration
3 | description: Configure Prettier code formatting for PocketPages using prettier-plugin-ejs. Install the plugin via package manager, add configuration to package.json, and format EJS templates with standard Prettier options.
4 | ---
5 |
6 | # Prettier PocketPages
7 |
8 | If you like using Prettier to format your code, you'll be happy to know that [prettier-plugin-ejs](https://github.com/ecmel/prettier-plugin-ejs) works pretty well (but not perfectly).
9 |
10 | ```
11 | bun add -D prettier-plugin-ejs
12 | ```
13 |
14 | Then, in `package.json`:
15 |
16 | ```json
17 | "prettier": {
18 | "semi": false,
19 | "singleQuote": true,
20 | "trailingComma": "es5",
21 | "plugins": [
22 | "prettier-plugin-ejs"
23 | ]
24 | }
25 | ```
26 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/custom-domain-fly-cloudflare.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Speedrun: Connecting Your Fly.io App to a Custom Domain with Cloudflare Proxy'
3 | description: 'Step-by-step process to configure DNS records, SSL certificates, and domain verification between Fly.io and Cloudflare. Includes specific settings for A/AAAA records, CNAME verification, and SSL/TLS encryption modes.'
4 | ---
5 |
6 | # Speedrun: Connecting Your Fly.io App to a Custom Domain with Cloudflare Proxy
7 |
8 | Custom domains on your Fly.io app with Cloudflare in front can be a little complex because you must validate the domain on Fly.io BEFORE turning on Cloudflare proxying. Follow these steps.
9 |
10 | ## 1. Create the Fly.io App
11 |
12 | - Start by deploying your app on [Fly.io](https://fly.io/). Follow the standard process to get your app up and running.
13 |
14 | ## 2. Register Your Domain
15 |
16 | - If you haven't already, register your domain. It's often convenient to register it through [Cloudflare](https://cloudflare.com), which will also handle your DNS and proxying needs.
17 |
18 | ## 3. Configure DNS in Cloudflare
19 |
20 | - In Cloudflare's DNS settings, add **A** and **AAAA** records pointing to your Fly.io app's public IPv4 and IPv6 addresses.
21 | - **Important:** Turn off proxying (the orange cloud icon) for these records. This ensures that the Fly.io app can be accessed directly.
22 |
23 | ## 4. Add a Certificate in Fly.io
24 |
25 | - In your Fly.io dashboard, add an SSL certificate for your custom domain.
26 | - Since proxying is turned off, Fly.io should be able to validate the certificate immediately. Your app should now respond on your custom domain, but it's not yet proxied through Cloudflare.
27 |
28 | ## 5. Verify Domain Ownership and Proxying
29 |
30 | - From the Fly.io certificate area, add the **CNAME** record required for domain ownership verification.
31 | - **Important:** Turn off proxying for the CNAME record as well. Fly.io needs to verify ownership whenever the SSL certificate is renewed, which requires direct access.
32 | - Go back to Fly.io, check the certificate, and ensure domain ownership verification is successful.
33 |
34 | ## 6. Turn On Proxying in Cloudflare
35 |
36 | - Once everything is verified and working, return to Cloudflare and turn on proxying (enable the orange cloud) for your A and AAAA records.
37 | - In Cloudflare’s **SSL/TLS** settings, set the encryption mode to **Full** (not Full Strict) to ensure proper SSL handshakes between Cloudflare and Fly.io.
38 |
39 | ## 7. Test Your Setup
40 |
41 | - Finally, browse to your new domain to confirm everything is working as expected with Cloudflare proxying enabled.
42 |
43 | You now have a fully functioning Fly.io app served through a custom domain with Cloudflare as the proxy!
44 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/custom-domain-pockethost.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Speedrun: Setting Up a Custom Domain on PocketHost'
3 | description: "Configure DNS CNAME records, verify domain ownership via TXT records, and enable custom domains on PocketHost Pro. Uses Cloudflare's CNAME flattening for root domain support without www prefix."
4 | ---
5 |
6 | # Speedrun: Setting Up a Custom Domain on PocketHost
7 |
8 | Custom domains are a **Pro feature** on PocketHost, which also unlocks unlimited projects and domains—a great deal if you plan to manage multiple projects.
9 |
10 | ## 1. Add the Custom Domain in PocketHost
11 |
12 | - Go to your PocketHost instance dashboard.
13 | - In the settings, add your custom domain. If you haven't upgraded yet, switch to the Pro plan to enable this feature.
14 |
15 | ## 2. Configure DNS with Your Provider
16 |
17 | - Add a **CNAME** record pointing to your PocketHost instance using your DNS provider.
18 | - **Recommendation:** Use [Cloudflare](https://cloudflare.com) to manage your DNS, as it supports **CNAME flattening**. This allows you to CNAME directly to your root domain, avoiding the need to use `www`.
19 |
20 | ## 3. Verify Domain Ownership
21 |
22 | - After adding the CNAME, follow the instructions to contact **@noaxis** on Discord. He'll provide the **TXT record** needed for Cloudflare to verify your domain ownership.
23 |
24 | ## 4. Test Your Setup
25 |
26 | - Once everything is set up, test your configuration by browsing to your custom domain to ensure everything is working as expected.
27 |
28 | By following these steps, you can easily set up a custom domain for your PocketHost projects and take advantage of the Pro plan's features.
29 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-54-56.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-54-56.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-56-00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-56-00.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-56-28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-56-28.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-56-56.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-56-56.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-07.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-19.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-27.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-57-57.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-58-27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-58-27.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-58-37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-58-37.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-00.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-00.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-09.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-17.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-24.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-32.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-06-59-59.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-07-00-42.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-07-00-42.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-15-28-44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/google-oauth2/2025-02-08-15-28-44.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-04-47.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-04-47.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-06-15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-06-15.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-07-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-07-10.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-07-35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-07-35.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-11-38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-11-38.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-12-14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-12-14.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-12-59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-12-59.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-14-04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-14-04.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-15-06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-15-06.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-21-45.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-21-45.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-24-55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-24-55.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-25-14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-25-14.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-25-59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-25-59.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-39-27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-39-27.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-51-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-51-48.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-56-56.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-56-56.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-57-35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/gs-gmail/2024-09-08-19-57-35.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-03-06-20-55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-03-06-20-55.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-03-07-00-59.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-03-07-00-59.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-20-29-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-20-29-10.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-20-30-52.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-20-30-52.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-20-33-41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-20-33-41.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-28-33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-28-33.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-32-26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-32-26.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-33-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-33-32.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-35-46.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-35-46.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-38-12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-38-12.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-38-51.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-38-51.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-41-08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-41-08.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-42-35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-42-35.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-45-05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-45-05.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-48-53.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-48-53.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-53-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benallfree/pocketpages/273886e5f7c1fa07346bb6927b050fe03d7a4930/packages/site/pb_hooks/pages/(main)/docs/speedruns/ses/2024-09-08-22-53-02.png
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/static-content.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Serving Static Content in PocketPages
3 | description: Static content in PocketPages includes files like HTML, CSS, JavaScript, images, and documents that are served directly to clients without server-side processing. The Echo framework manages content type inference, streaming, and caching for these files.
4 | ---
5 |
6 | # Serving Static Content in PocketPages
7 |
8 | In PocketPages, serving static content is straightforward and integrated seamlessly into the framework. Any file that isn't an EJS template (`*.ejs`), doesn't begin with a `+`, and isn't in a `_private` directory is treated as a static file. These files are served directly by the underlying Echo framework, which handles content type inference, streaming, and other necessary details.
9 |
10 | ## What is Considered Static Content?
11 |
12 | Static content refers to files that are served directly to the client without server-side processing or dynamic generation. These files typically include:
13 |
14 | - HTML files (`*.html`)
15 | - CSS files (`*.css`)
16 | - JavaScript files (`*.js`)
17 | - Image files (`*.jpg`, `*.png`, etc.)
18 | - Font files (`*.woff`, `*.ttf`, etc.)
19 | - Other binary files or documents (e.g., PDFs, videos)
20 |
21 | For dynamic asset handling in your templates and pages, PocketPages provides the `asset()` function that helps generate correct URLs for your static assets. This function ensures your assets are properly referenced regardless of your application's base path configuration.
22 |
23 | For more details on managing and organizing your static assets effectively, see the [Asset Management Guide](/docs/guides/asset-management).
24 |
25 | ### Example Directory Structure
26 |
27 | ```plaintext
28 | my-pocketpages-app/
29 | ├── pages/
30 | │ ├── assets/ # Static assets directory
31 | │ │ ├── css/
32 | │ │ │ ├── main.css
33 | │ │ │ └── components.css
34 | │ │ ├── js/
35 | │ │ │ ├── app.js
36 | │ │ │ └── utils.js
37 | │ │ ├── images/
38 | │ │ │ ├── logo.png
39 | │ │ │ └── hero.jpg
40 | │ │ └── fonts/
41 | │ │ ├── OpenSans.woff2
42 | │ │ └── Roboto.woff2
43 | │ ├── documents/ # Static documents
44 | │ │ ├── terms.pdf
45 | │ │ └── privacy.pdf
46 | │ ├── layout.ejs # Layout template (not served as static)
47 | │ ├── +middleware.js # Middleware file (not served as static)
48 | │ ├── index.ejs # Dynamic page template
49 | │ └── about.html # Static HTML page
50 | ```
51 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/structure.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Recommended Project Structure
3 | description: Standard directory layout for PocketBase projects with hooks, migrations, and data storage, compatible with pockethost.io deployment and local development.
4 | ---
5 |
6 | # Recommended Project Structure
7 |
8 | This recommended project structure makes it easy to upload everything in `/pb_*` directly to your production PocketBase instance. It also mirrors the directory structure of [pockethost.io](https://pockethost.io) and PocketBase's sample directory names.
9 |
10 | ```
11 | package.json
12 | pb_hooks/
13 | pages/
14 | +boot.pb.js
15 | index.ejs
16 | pb_migrations/
17 | pb_data/
18 | storage/
19 | data.db
20 | logs.db
21 | ```
22 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/toc.md:
--------------------------------------------------------------------------------
1 | # Quick Start
2 |
3 | - [Introduction](/docs/introduction)
4 | - [Quick Start Guide](/docs/quickstart)
5 | - [Project Setup](/docs/setup)
6 | - [TypeScript Support](/docs/typescript)
7 |
8 | # Core Concepts
9 |
10 | - [Pages](/docs/pages)
11 |
12 | - [File-based Routing](/docs/routing)
13 | - [Dynamic Routes](/docs/dynamic-routes)
14 | - [Route Parameters](/docs/params)
15 |
16 | - [Data Flow](/docs/data)
17 |
18 | - [Data Loading](/docs/data-loading)
19 | - [Form Handling](/docs/forms)
20 | - [Database Access](/docs/database)
21 | - [Authentication](/docs/auth)
22 |
23 | - [Templates](/docs/templates)
24 | - [EJS Syntax](/docs/ejs)
25 | - [Layouts](/docs/layouts)
26 | - [Partials](/docs/partials)
27 | - [Slots](/docs/slots)
28 |
29 | # Request Context
30 |
31 | - [Overview](/docs/context)
32 | - [Request Object](/docs/request)
33 | - [Response Object](/docs/response)
34 | - [Form Data](/docs/form-data)
35 | - [Parameters](/docs/params)
36 | - [Session](/docs/session)
37 |
38 | # Asset Pipeline
39 |
40 | - [Asset Management](/docs/assets)
41 | - [Static Files](/docs/static)
42 | - [Resource Resolution](/docs/resolve)
43 | - [Private Files](/docs/private)
44 | - [Meta Tags](/docs/meta)
45 |
46 | # PocketBase Integration
47 |
48 | - [JSVM Overview](/docs/jsvm)
49 | - [Database Access](/docs/db)
50 | - [Authentication](/docs/auth)
51 | - [File Storage](/docs/files)
52 | - [Collections](/docs/collections)
53 |
54 | # Utilities
55 |
56 | - [Environment Variables](/docs/env)
57 | - [Logging](/docs/logging)
58 | - [URL Handling](/docs/url)
59 | - [JSON Operations](/docs/json)
60 | - [Collection Helpers](/docs/collections)
61 |
62 | # Deployment
63 |
64 | - [Production Checklist](/docs/production)
65 | - [Environment Setup](/docs/environments)
66 | - [Caching Strategies](/docs/caching)
67 | - [Security Best Practices](/docs/security)
68 | - [Performance Tips](/docs/performance)
69 |
70 | # Integrations
71 |
72 | - [HTMX Guide](/docs/htmx)
73 | - [AlpineJS Guide](/docs/alpine)
74 | - [TailwindCSS](/docs/tailwind)
75 | - [Markdown Processing](/docs/markdown)
76 |
77 | # Recipes
78 |
79 | - [Authentication Flow](/docs/recipes/auth)
80 | - [File Uploads](/docs/recipes/uploads)
81 | - [API Endpoints](/docs/recipes/api)
82 | - [Custom Domains](/docs/recipes/domains)
83 | - [Email Setup](/docs/recipes/email)
84 |
85 | # Development
86 |
87 | - [IDE Setup](/docs/ide)
88 | - [Debugging](/docs/debug)
89 | - [Testing](/docs/testing)
90 | - [Type System](/docs/types)
91 | - [Contributing](/docs/contributing)
92 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/upgrading.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Upgrading PocketPages'
3 | description: 'Step-by-step instructions for upgrading PocketPages using tiged.'
4 | ---
5 |
6 | # Upgrading PocketPages
7 |
8 | PocketPages ships as an NPM package. Keeping it up to date ensures you have access to the latest features, improvements, and security patches. The upgrade process is simple:
9 |
10 | ```bash
11 | # Update PocketPages in your project
12 | npm i pocketpages@latest
13 | ```
14 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(main)/docs/vscode.md:
--------------------------------------------------------------------------------
1 | # VS Code / Cursor Enhancements for PocketPages
2 |
3 | PocketPages includes some helpful VS Code configurations to improve your development experience. You can add these to your project by copying the `.vscode` directory from the PocketPages starter files:
4 |
5 | ```bash
6 | cp .vscode .vscode-backup
7 | cp -r ./node_modules/pocketpages/starters/vscode .
8 | ```
9 |
10 | ## Features
11 |
12 | ### EJS Formatting
13 |
14 | The configuration includes [EJS Beautifier](https://marketplace.visualstudio.com/items?itemName=j69.ejs-beautify) as the default formatter for HTML files. This ensures your EJS templates stay properly formatted.
15 |
16 | To use:
17 |
18 | 1. Install the EJS Beautifier extension
19 | 2. Format your EJS files using `Alt+Shift+F` (Windows/Linux) or `Cmd+Shift+F` (Mac)
20 |
21 | ### Code Snippets
22 |
23 | Common PocketPages patterns are available as VS Code snippets:
24 |
25 | #### `ppld`
26 |
27 | Creates a new loader function with proper TypeScript types:
28 |
29 | ```javascript
30 | /** @type {import('pocketpages').PageDataLoaderFunc} */
31 | module.exports = (api) => {
32 | const { dbg } = api
33 |
34 | dbg(new loader(), { api })
35 |
36 | return {}
37 | }
38 | ```
39 |
40 | #### `ppmd`
41 |
42 | Creates a new middleware function with proper TypeScript types:
43 |
44 | ```javascript
45 | /** @type {import('pocketpages').MiddlewareFunc} */
46 | module.exports = (api) => {
47 | const { dbg } = api
48 |
49 | dbg(new loader(), { api })
50 |
51 | return {}
52 | }
53 | ```
54 |
55 | To use snippets:
56 |
57 | 1. Type the snippet prefix (e.g., `ppld`)
58 | 2. Press `Tab` to insert the snippet
59 | 3. Use `Tab` to move between the customizable fields
60 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(splash)/+layout.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%- slot %>
4 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(splash)/+load.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @type {import('pocketpages').PageDataLoaderFunc}
3 | */
4 | const load = (context) => {
5 | return {
6 | version: require(`${__hooks}/../package.json`).version,
7 | }
8 | }
9 |
10 | module.exports = load
11 |
--------------------------------------------------------------------------------
/packages/site/pb_hooks/pages/(splash)/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
PocketPages
5 |
6 |
7 | Build faster with Server-Side web pages - no build chain or complicated
8 | tech stack required.
9 |