The Legal Service manages legal content pages including privacy policy and terms of service documents.
Overview
This service provides methods to retrieve and update legal pages using a slug-based identification system.
Dependencies
legalRepository - Database operations for legal pages
Methods
getLegalPages()
Retrieves both privacy and terms pages.
import { legalService } from '$lib/server/services/legal.service.js';
const { privacidad, terminos } = await legalService.getLegalPages();
Privacy policy page object:
id: Page identifier
slug: Page slug (‘privacidad’)
title: Page title
content: Page content (HTML or markdown)
Terms of service page object:
id: Page identifier
slug: Page slug (‘terminos’)
title: Page title
content: Page content (HTML or markdown)
Example Response
{
privacidad: {
id: 1,
slug: 'privacidad',
title: 'Política de Privacidad',
content: '<h1>Política de Privacidad</h1><p>...</p>'
},
terminos: {
id: 2,
slug: 'terminos',
title: 'Términos y Condiciones',
content: '<h1>Términos y Condiciones</h1><p>...</p>'
}
}
Returns null for pages that don’t exist.
Implementation Details
Source: src/lib/server/services/legal.service.js:4-10
const pages = await legalRepository.getAll();
const privacidad = pages.find((p) => p.slug === 'privacidad') || null;
const terminos = pages.find((p) => p.slug === 'terminos') || null;
return { privacidad, terminos };
getBySlug()
Retrieves a specific legal page by its slug.
import { legalService } from '$lib/server/services/legal.service.js';
const privacyPage = await legalService.getBySlug('privacidad');
const termsPage = await legalService.getBySlug('terminos');
Page slug. Typically 'privacidad' or 'terminos'
Legal page object or null if not found:
id: Page identifier
slug: Page slug
title: Page title
content: Page content
Implementation Details
Source: src/lib/server/services/legal.service.js:13-15
updateLegalPage()
Updates or creates a legal page (upsert by slug).
import { legalService } from '$lib/server/services/legal.service.js';
await legalService.updateLegalPage('privacidad', {
title: 'Política de Privacidad',
content: `
<h1>Política de Privacidad</h1>
<p>En PROVESA respetamos tu privacidad...</p>
<h2>Recolección de Datos</h2>
<p>Recolectamos los siguientes datos...</p>
`
});
Page slug to update. Use 'privacidad' or 'terminos'
Page content (HTML or markdown)
This is an upsert operation. If the page doesn’t exist, it will be created. If it exists, it will be updated.
Implementation Details
Source: src/lib/server/services/legal.service.js:18-20
Usage Examples
Complete Legal Pages Management
// src/routes/admin/legal/+page.server.js
import { legalService } from '$lib/server/services/legal.service.js';
import { fail } from '@sveltejs/kit';
export async function load() {
const { privacidad, terminos } = await legalService.getLegalPages();
return { privacidad, terminos };
}
export const actions = {
updatePrivacy: async ({ request }) => {
const formData = await request.formData();
try {
await legalService.updateLegalPage('privacidad', {
title: formData.get('title'),
content: formData.get('content')
});
return { success: true };
} catch (error) {
return fail(500, { error: error.message });
}
},
updateTerms: async ({ request }) => {
const formData = await request.formData();
try {
await legalService.updateLegalPage('terminos', {
title: formData.get('title'),
content: formData.get('content')
});
return { success: true };
} catch (error) {
return fail(500, { error: error.message });
}
}
};
Display Legal Pages on Frontend
// src/routes/legal/[slug]/+page.server.js
import { legalService } from '$lib/server/services/legal.service.js';
import { error } from '@sveltejs/kit';
export async function load({ params }) {
const page = await legalService.getBySlug(params.slug);
if (!page) {
throw error(404, 'Página no encontrada');
}
return { page };
}
<!-- src/routes/legal/[slug]/+page.svelte -->
<script>
export let data;
</script>
<article class="legal-page">
<h1>{data.page.title}</h1>
<div class="content">
{@html data.page.content}
</div>
</article>
Admin Editor with Rich Text
<!-- src/routes/admin/legal/+page.svelte -->
<script>
import { enhance } from '$app/forms';
export let data;
export let form;
let activeTab = 'privacidad';
</script>
<div class="legal-editor">
<div class="tabs">
<button
class:active={activeTab === 'privacidad'}
on:click={() => activeTab = 'privacidad'}
>
Privacidad
</button>
<button
class:active={activeTab === 'terminos'}
on:click={() => activeTab = 'terminos'}
>
Términos
</button>
</div>
{#if activeTab === 'privacidad'}
<form method="POST" action="?/updatePrivacy" use:enhance>
<div>
<label for="privacy-title">Título</label>
<input
type="text"
id="privacy-title"
name="title"
value={data.privacidad?.title || ''}
required
/>
</div>
<div>
<label for="privacy-content">Contenido</label>
<textarea
id="privacy-content"
name="content"
rows="20"
required
>{data.privacidad?.content || ''}</textarea>
</div>
<button type="submit">Guardar Privacidad</button>
</form>
{:else}
<form method="POST" action="?/updateTerms" use:enhance>
<div>
<label for="terms-title">Título</label>
<input
type="text"
id="terms-title"
name="title"
value={data.terminos?.title || ''}
required
/>
</div>
<div>
<label for="terms-content">Contenido</label>
<textarea
id="terms-content"
name="content"
rows="20"
required
>{data.terminos?.content || ''}</textarea>
</div>
<button type="submit">Guardar Términos</button>
</form>
{/if}
{#if form?.success}
<p class="success">Cambios guardados exitosamente</p>
{/if}
{#if form?.error}
<p class="error">{form.error}</p>
{/if}
</div>
Data Structure
Legal Page Object
interface LegalPage {
id: number;
slug: 'privacidad' | 'terminos';
title: string;
content: string; // HTML or markdown
}
Page Slugs
| Slug | Purpose | Common Title (Spanish) |
|---|
privacidad | Privacy policy | Política de Privacidad |
terminos | Terms of service | Términos y Condiciones |
Content Formats
HTML Content
await legalService.updateLegalPage('privacidad', {
title: 'Política de Privacidad',
content: `
<section>
<h2>1. Información que Recopilamos</h2>
<p>Recopilamos información que usted nos proporciona directamente...</p>
</section>
<section>
<h2>2. Cómo Usamos su Información</h2>
<ul>
<li>Para procesar sus pedidos</li>
<li>Para mejorar nuestros servicios</li>
<li>Para comunicarnos con usted</li>
</ul>
</section>
`
});
Markdown Content
await legalService.updateLegalPage('terminos', {
title: 'Términos y Condiciones',
content: `
# Términos y Condiciones
## 1. Aceptación de Términos
Al acceder y utilizar este sitio web, usted acepta estar sujeto a estos términos...
## 2. Uso del Sitio
Usted se compromete a:
- Usar el sitio solo con fines lícitos
- No interrumpir el funcionamiento del sitio
- Respetar los derechos de propiedad intelectual
`
});
If using markdown, you’ll need to render it as HTML on the frontend using a markdown parser.
Legal Page Templates
Privacy Policy Template
const privacyTemplate = {
title: 'Política de Privacidad',
content: `
<h1>Política de Privacidad</h1>
<h2>1. Información que Recopilamos</h2>
<p>Recopilamos información personal que usted nos proporciona voluntariamente cuando se registra en el sitio, realiza una compra, o se comunica con nosotros.</p>
<h2>2. Cómo Usamos su Información</h2>
<p>Utilizamos la información recopilada para:</p>
<ul>
<li>Procesar sus transacciones</li>
<li>Mejorar nuestro sitio web</li>
<li>Enviar correos electrónicos periódicos</li>
</ul>
<h2>3. Protección de la Información</h2>
<p>Implementamos medidas de seguridad para mantener la seguridad de su información personal.</p>
<h2>4. Divulgación a Terceros</h2>
<p>No vendemos, comercializamos ni transferimos su información personal a terceros.</p>
<h2>5. Consentimiento</h2>
<p>Al usar nuestro sitio, usted consiente nuestra política de privacidad.</p>
`
};
await legalService.updateLegalPage('privacidad', privacyTemplate);
Terms of Service Template
const termsTemplate = {
title: 'Términos y Condiciones',
content: `
<h1>Términos y Condiciones</h1>
<h2>1. Aceptación de Términos</h2>
<p>Al acceder y usar este sitio web, usted acepta cumplir con estos términos y condiciones.</p>
<h2>2. Uso del Sitio</h2>
<p>Usted acepta usar el sitio solo para fines legales y de manera que no infrinja los derechos de otros.</p>
<h2>3. Propiedad Intelectual</h2>
<p>Todo el contenido de este sitio es propiedad de PROVESA y está protegido por leyes de derechos de autor.</p>
<h2>4. Limitación de Responsabilidad</h2>
<p>PROVESA no será responsable de daños derivados del uso o la imposibilidad de usar este sitio.</p>
<h2>5. Modificaciones</h2>
<p>Nos reservamos el derecho de modificar estos términos en cualquier momento.</p>
<h2>6. Contacto</h2>
<p>Si tiene preguntas sobre estos términos, contáctenos en contacto@provesa.com</p>
`
};
await legalService.updateLegalPage('terminos', termsTemplate);
Best Practices
Always consult with legal professionals before publishing privacy policies or terms of service.
Use semantic HTML for better accessibility and SEO.
Include a “Last Updated” date in your legal page content.
Legal pages should be reviewed and updated regularly to comply with current laws and regulations.
Rich Text Editor Integration
For a better editing experience, integrate a rich text editor:
<script>
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import { onMount } from 'svelte';
let editor;
let editorElement;
onMount(() => {
editor = new Editor({
element: editorElement,
extensions: [StarterKit],
content: data.privacidad?.content || '',
onUpdate: ({ editor }) => {
// Get HTML content
const html = editor.getHTML();
// Store in hidden input for form submission
}
});
return () => {
editor.destroy();
};
});
</script>
<div bind:this={editorElement}></div>
Compliance Considerations
GDPR Compliance
If serving EU users, ensure your privacy policy covers:
- Data collection and usage
- User rights (access, deletion, portability)
- Cookie usage
- Data retention policies
- Contact information for privacy inquiries
Common Legal Page Sections
Privacy Policy:
- Information Collection
- Information Usage
- Information Protection
- Cookie Policy
- Third-Party Disclosure
- User Rights
- Contact Information
Terms of Service:
- Acceptance of Terms
- Site Usage Rules
- Intellectual Property
- User Accounts
- Limitation of Liability
- Termination Rights
- Governing Law