Skip to main content

Overview

Public sharing allows you to make prompts accessible to anyone with the link, without requiring authentication. Shared prompts are read-only and display only the latest version’s content.

Enabling Public Sharing

Toggle Public Status

Make a prompt public or private:
import { togglePromptPublic } from '@/features/prompts/actions/manage-prompt';

// Make public
await togglePromptPublic(promptId, true);

// Make private
await togglePromptPublic(promptId, false);
Implementation from src/features/prompts/actions/manage-prompt.ts:76-94:
export async function togglePromptPublic(
  promptId: string,
  isPublic: boolean,
): Promise<PromptActionResult> {
  const { supabase, user } = await requireUser();
  if (!user) return { success: false, error: 'Unauthorized' };

  const { error } = await supabase
    .from('prompts')
    .update({ is_public: isPublic })
    .eq('id', promptId);

  if (error) {
    return { success: false, error: `Failed to update sharing: ${error.message}` };
  }

  revalidatePath('/');
  return { success: true };
}
This sets the is_public boolean flag on the prompt.
Only the prompt owner can toggle public status. Row Level Security (RLS) policies enforce this.

Public URLs

URL Format

Public prompts are accessible at:
https://your-app.com/p/[promptId]
Example:
https://promptrepo.com/p/550e8400-e29b-41d4-a716-446655440000
The /p/ route is specifically designed for unauthenticated public access.

Implementation

The public page is implemented in src/app/p/[promptId]/page.tsx:8-31:
export default async function PublicPromptPage({ params }: PublicPromptPageProps) {
  const { promptId } = await params;
  const prompt = await getPublicPrompt(promptId);

  if (!prompt) {
    notFound();
  }

  return (
    <div className="min-h-screen bg-background">
      <div className="container max-w-2xl px-4 py-10">
        <div className="mb-6 space-y-1">
          <h1 className="text-2xl font-bold tracking-tight text-foreground">
            {prompt.title}
          </h1>
          {prompt.description && (
            <p className="text-sm text-muted-foreground">
              {prompt.description}
            </p>
          )}
        </div>
        <div className="rounded-md border border-border bg-card p-4 font-mono text-sm leading-relaxed text-foreground whitespace-pre-wrap shadow-sm">
          {prompt.latest_content}
        </div>
      </div>
    </div>
  );
}
The public page is a Server Component that fetches data without requiring authentication.

Fetching Public Prompts

Public Client

Public prompts use a special Supabase client that bypasses RLS:
import { getPublicPrompt } from '@/features/prompts/queries/get-public-prompt';

const prompt = await getPublicPrompt(promptId);
Implementation from src/features/prompts/queries/get-public-prompt.ts:14-46:
export async function getPublicPrompt(promptId: string): Promise<PublicPrompt | null> {
  const supabase = createPublicClient();

  const { data, error } = await supabase
    .from('prompts')
    .select(`
      id,
      title,
      description,
      prompt_versions (
        content,
        version_number
      )
    `)
    .eq('id', promptId)
    .eq('is_public', true)  // Only return if public
    .maybeSingle();

  if (error || !data) {
    return null;
  }

  const response = data as unknown as DbPublicPromptResponse;
  const versions = response.prompt_versions || [];
  const latestVersion = versions.sort((a, b) => 
    b.version_number - a.version_number
  )[0];

  return {
    id: response.id,
    title: response.title,
    description: response.description,
    latest_content: latestVersion?.content || '',
  };
}

Public Prompt Type

Public prompts expose limited information:
interface PublicPrompt {
  id: string;
  title: string;
  description: string | null;
  latest_content: string;  // Only the latest version
}
From src/features/prompts/types/index.ts:12-17.
Public prompts do not expose:
  • Version history
  • User information
  • Creation/update timestamps
  • Archive status
  • Collection associations

Database Schema

is_public Flag

From supabase/migrations/20260227000007_prompt_public_sharing.sql:
ALTER TABLE prompts 
  ADD COLUMN is_public BOOLEAN DEFAULT false NOT NULL;

CREATE INDEX idx_prompts_is_public ON prompts(is_public);
The index optimizes queries for public prompts.

RLS Policy

Public prompts have a special RLS policy:
CREATE POLICY "Anyone can view public prompts" 
  ON prompts FOR SELECT 
  USING (is_public = true);
This allows unauthenticated users to read public prompts without bypassing RLS entirely.

Security Considerations

What’s Exposed

When you make a prompt public:
  • Title and description are visible
  • Latest version content is visible
  • Prompt ID is visible in the URL

What’s Protected

  • Version history is not accessible
  • User identity is not exposed
  • Other prompts by the same user are not discoverable
  • Edit/delete operations are not possible
  • Variable values from snapshots are not exposed
Do not include sensitive information (API keys, passwords, personal data) in prompts you plan to share publicly.

Middleware Bypass

The /p/* route is excluded from authentication middleware:
// From src/middleware.ts
export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$|p/).*)',
  ],
};
This allows unauthenticated access to public sharing URLs.

Use Cases

Portfolio

Share your best prompts publicly:
Title: "Advanced Code Review Prompt"
Public URL: /p/abc123
Use: Include in your portfolio or resume

Documentation

Embed prompts in documentation:
## Example Prompt

See our [customer support template](/p/def456) for reference.

Team Sharing

Share with team members without requiring accounts:
Hey team, check out this prompt: https://promptrepo.com/p/ghi789
Feel free to copy and adapt it for your needs.

Education

Share prompts in courses or tutorials:
Lesson 5: See the [example prompt](/p/jkl012) demonstrating 
variable usage.

Revoking Access

Make Private

Revoke public access at any time:
await togglePromptPublic(promptId, false);
The public URL will immediately return a 404 error.
Making a prompt private does not invalidate existing links. Users will simply see a “Not Found” page.

No Tracking

PromptRepo does not track:
  • Who accesses public links
  • How many times a link is accessed
  • When a link is accessed
This is intentional to keep the system simple and privacy-focused.

Limitations

No versioning: Public URLs always show the latest version. If you update the prompt, the public link updates too.
No comments or feedback: Public viewers cannot leave comments or provide feedback directly.
No analytics: You cannot see view counts, visitor demographics, or access patterns.
No collaboration: Public sharing is read-only. Viewers must copy the content to use it.

Best Practices

Review Before Sharing

Always review prompt content before making it public. Ensure no sensitive information is included.

Clear Descriptions

Add helpful descriptions to public prompts. Viewers see this context on the public page.

Version Stability

Remember that public URLs reflect the latest version. If you need to share a specific version, consider copying it to a new prompt first.

License Information

If you want to specify how others can use your prompt (e.g., Creative Commons), include this in the description.

API Access

MCP Server

Public prompts can be accessed via the MCP API without authentication:
curl -X POST https://your-app/api/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "get_prompt",
      "arguments": { "id": "prompt-uuid" }
    }
  }'
Without an API key, only public prompts are returned.

Direct Database Query

If you’re building a custom integration:
const { data } = await supabase
  .from('prompts')
  .select('id, title, description')
  .eq('is_public', true);
This requires a Supabase client with appropriate RLS policies.

Future Enhancements

Potential features for public sharing:
  • View counts: Track how many times a prompt is accessed
  • Comments: Allow public feedback
  • Embedding: Generate embeddable widgets
  • Version pinning: Share specific versions instead of always latest
  • Custom slugs: Use readable URLs like /p/my-awesome-prompt
  • Search: Public prompt directory
These are not currently implemented.

Next Steps

Prompt Management

Learn about prompt lifecycle and metadata

Version Control

Understand how versions work with public sharing

Collections

Organize prompts before sharing

MCP API

Access public prompts programmatically

Build docs developers (and LLMs) love