Default Theme: Edit Link
Learn how to configure and customize edit links in the VitePress default theme.
Overview
Edit links allow users to quickly navigate to the source file to suggest changes or corrections. VitePress provides built-in support for edit links with various hosting providers.
Basic Configuration
GitHub Edit Links
Configure edit links for GitHub repositories:
// .vitepress/config.js
export default {
themeConfig: {
editLink: {
pattern: 'https://github.com/username/repository/edit/main/docs/:path',
text: 'Edit this page on GitHub'
}
}
}
GitLab Edit Links
Configure for GitLab repositories:
export default {
themeConfig: {
editLink: {
pattern: 'https://gitlab.com/username/repository/-/edit/main/docs/:path',
text: 'Edit this page on GitLab'
}
}
}
Bitbucket Edit Links
Configure for Bitbucket repositories:
export default {
themeConfig: {
editLink: {
pattern: 'https://bitbucket.org/username/repository/src/main/docs/:path?mode=edit',
text: 'Edit this page on Bitbucket'
}
}
}
Advanced Configuration
Conditional Edit Links
Show edit links only for specific pages:
export default {
themeConfig: {
editLink: {
pattern: ({ filePath }) => {
// Only show edit links for guide pages
if (filePath.startsWith('guide/')) {
return `https://github.com/username/repository/edit/main/docs/${filePath}`
}
// No edit link for other pages
return false
},
text: 'Suggest changes'
}
}
}
Branch-specific Edit Links
Use different branches for different sections:
export default {
themeConfig: {
editLink: {
pattern: ({ filePath }) => {
const branch = filePath.startsWith('api/') ? 'api-docs' : 'main'
return `https://github.com/username/repository/edit/${branch}/docs/${filePath}`
},
text: 'Edit this page'
}
}
}
Repository-specific Edit Links
Use different repositories for different sections:
export default {
themeConfig: {
editLink: {
pattern: ({ filePath }) => {
if (filePath.startsWith('api/')) {
return `https://github.com/username/api-docs/edit/main/${filePath}`
}
if (filePath.startsWith('examples/')) {
return `https://github.com/username/examples/edit/main/docs/${filePath}`
}
return `https://github.com/username/main-docs/edit/main/docs/${filePath}`
},
text: ({ filePath }) => {
if (filePath.startsWith('api/')) return 'Edit API docs'
if (filePath.startsWith('examples/')) return 'Edit example'
return 'Edit this page'
}
}
}
}
Localization
Multi-language Edit Links
Configure edit links for different locales:
export default {
locales: {
root: {
themeConfig: {
editLink: {
pattern: 'https://github.com/username/repository/edit/main/docs/:path',
text: 'Edit this page on GitHub'
}
}
},
zh: {
themeConfig: {
editLink: {
pattern: 'https://github.com/username/repository/edit/main/docs/:path',
text: '在 GitHub 上编辑此页面'
}
}
},
es: {
themeConfig: {
editLink: {
pattern: 'https://github.com/username/repository/edit/main/docs/:path',
text: 'Editar esta página en GitHub'
}
}
}
}
}
Locale-specific Repositories
Use different repositories for different languages:
export default {
locales: {
root: {
themeConfig: {
editLink: {
pattern: 'https://github.com/username/docs-en/edit/main/:path',
text: 'Edit this page'
}
}
},
zh: {
themeConfig: {
editLink: {
pattern: 'https://github.com/username/docs-zh/edit/main/:path',
text: '编辑此页面'
}
}
}
}
}
Customization
Custom Edit Link Component
Create a custom edit link component:
<!-- .vitepress/theme/components/CustomEditLink.vue -->
<template>
<div v-if="editUrl" class="custom-edit-link">
<a
:href="editUrl"
target="_blank"
rel="noopener noreferrer"
class="edit-link-button"
>
<EditIcon class="edit-icon" />
{{ editText }}
<ExternalLinkIcon class="external-icon" />
</a>
<div class="edit-help">
<p>Found an error? Help us improve this page!</p>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { useData } from 'vitepress'
import EditIcon from './icons/EditIcon.vue'
import ExternalLinkIcon from './icons/ExternalLinkIcon.vue'
const { page, theme } = useData()
const editUrl = computed(() => {
const { editLink } = theme.value
if (!editLink) return null
const { pattern } = editLink
if (typeof pattern === 'function') {
return pattern({ filePath: page.value.relativePath })
}
return pattern.replace(':path', page.value.relativePath)
})
const editText = computed(() => {
const { editLink } = theme.value
if (!editLink) return 'Edit this page'
const { text } = editLink
if (typeof text === 'function') {
return text({ filePath: page.value.relativePath })
}
return text || 'Edit this page'
})
</script>
<style scoped>
.custom-edit-link {
margin: 32px 0;
padding: 16px;
border: 1px solid var(--vp-c-border);
border-radius: 8px;
background: var(--vp-c-bg-soft);
}
.edit-link-button {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
background: var(--vp-c-brand-1);
color: white;
text-decoration: none;
border-radius: 6px;
font-weight: 500;
transition: background-color 0.2s;
}
.edit-link-button:hover {
background: var(--vp-c-brand-2);
}
.edit-icon,
.external-icon {
width: 16px;
height: 16px;
}
.edit-help {
margin-top: 12px;
font-size: 14px;
color: var(--vp-c-text-2);
}
.edit-help p {
margin: 0;
}
</style>
Integration with Custom Theme
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import CustomEditLink from './components/CustomEditLink.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('CustomEditLink', CustomEditLink)
}
}
Styling
Default Edit Link Styling
Customize the default edit link appearance:
/* Custom edit link styles */
.vp-doc-footer .edit-link {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border: 1px solid var(--vp-c-border);
border-radius: 6px;
text-decoration: none;
color: var(--vp-c-text-1);
font-size: 14px;
font-weight: 500;
transition: all 0.2s;
}
.vp-doc-footer .edit-link:hover {
border-color: var(--vp-c-brand-1);
color: var(--vp-c-brand-1);
background: var(--vp-c-brand-soft);
}
.vp-doc-footer .edit-link .vpi-square-pen {
width: 16px;
height: 16px;
}
Button-style Edit Link
Make edit links look like buttons:
.vp-doc-footer .edit-link {
background: var(--vp-c-brand-1);
color: white;
border: none;
padding: 10px 16px;
border-radius: 6px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
font-size: 12px;
}
.vp-doc-footer .edit-link:hover {
background: var(--vp-c-brand-2);
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
Integration with Git Providers
GitHub Integration
Enhanced GitHub integration with additional features:
export default {
themeConfig: {
editLink: {
pattern: ({ filePath }) => {
const baseUrl = 'https://github.com/username/repository'
const branch = 'main'
const path = `docs/${filePath}`
// Add line numbers for specific file types
if (filePath.endsWith('.md')) {
return `${baseUrl}/edit/${branch}/${path}`
}
return `${baseUrl}/blob/${branch}/${path}`
},
text: ({ filePath }) => {
if (filePath.endsWith('.md')) {
return 'Edit this page'
}
return 'View source'
}
}
}
}
GitLab Integration
Enhanced GitLab integration:
export default {
themeConfig: {
editLink: {
pattern: ({ filePath }) => {
const baseUrl = 'https://gitlab.com/username/repository'
const branch = 'main'
const path = `docs/${filePath}`
return `${baseUrl}/-/edit/${branch}/${path}`
},
text: 'Edit on GitLab'
}
}
}
Analytics and Tracking
Track Edit Link Clicks
Add analytics tracking to edit links:
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
// Track edit link clicks
document.addEventListener('click', (event) => {
const editLink = event.target.closest('.edit-link')
if (editLink) {
// Google Analytics
if (typeof gtag !== 'undefined') {
gtag('event', 'edit_link_click', {
event_category: 'engagement',
event_label: window.location.pathname
})
}
// Custom analytics
if (typeof analytics !== 'undefined') {
analytics.track('Edit Link Clicked', {
page: window.location.pathname,
url: editLink.href
})
}
}
})
})
</script>
A/B Testing Edit Links
Test different edit link styles:
<script setup>
import { ref, onMounted } from 'vue'
const editLinkVariant = ref('A')
onMounted(() => {
// Simple A/B testing
editLinkVariant.value = Math.random() > 0.5 ? 'A' : 'B'
// Track variant
if (typeof gtag !== 'undefined') {
gtag('event', 'edit_link_variant', {
event_category: 'experiment',
event_label: editLinkVariant.value
})
}
})
</script>
<template>
<a
:class="[
'edit-link',
`edit-link--variant-${editLinkVariant}`
]"
:href="editUrl"
>
{{ editText }}
</a>
</template>
Accessibility
Screen Reader Support
Make edit links accessible:
<template>
<a
:href="editUrl"
class="edit-link"
:aria-label="`Edit ${pageTitle} on GitHub`"
target="_blank"
rel="noopener noreferrer"
>
<span class="edit-icon" aria-hidden="true">✏️</span>
<span class="edit-text">Edit this page</span>
<span class="sr-only">Opens in new tab</span>
</a>
</template>
<style scoped>
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
</style>
Keyboard Navigation
Ensure edit links work with keyboard navigation:
.edit-link:focus {
outline: 2px solid var(--vp-c-brand-1);
outline-offset: 2px;
}
.edit-link:focus:not(:focus-visible) {
outline: none;
}
Best Practices
User Experience
- Clear labeling - Use descriptive text for edit links
- Consistent placement - Place edit links in predictable locations
- Visual feedback - Provide hover and focus states
- External link indicators - Show when links open in new tabs
Performance
- Lazy loading - Load edit link components only when needed
- Minimal JavaScript - Keep edit link logic lightweight
- Efficient patterns - Use efficient URL pattern matching
- Caching - Cache computed edit URLs when possible
Security
- Validate URLs - Ensure edit URLs are safe
- HTTPS only - Use secure connections for edit links
- Trusted domains - Only link to trusted git providers
- Input sanitization - Sanitize file paths in URLs
Maintenance
- Test regularly - Verify edit links work correctly
- Monitor analytics - Track edit link usage
- Update patterns - Keep URL patterns current
- Document configuration - Maintain clear documentation
Troubleshooting
Common Issues
Edit links not appearing:
- Check if
editLink
is configured in theme config - Verify the pattern function returns a valid URL
- Ensure the page has a valid
relativePath
Wrong URLs generated:
- Check the pattern string or function
- Verify file path handling
- Test with different page types
Styling issues:
- Check CSS specificity
- Verify CSS variables are defined
- Test in different browsers
Debug Mode
Enable debug logging for edit links:
export default {
themeConfig: {
editLink: {
pattern: ({ filePath }) => {
const url = `https://github.com/username/repository/edit/main/docs/${filePath}`
if (process.env.NODE_ENV === 'development') {
console.log('Edit link generated:', { filePath, url })
}
return url
},
text: 'Edit this page'
}
}
}
Examples
Basic GitHub Setup
export default {
themeConfig: {
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
text: 'Edit this page on GitHub'
}
}
}
Advanced Multi-Repository Setup
export default {
themeConfig: {
editLink: {
pattern: ({ filePath }) => {
// API documentation in separate repo
if (filePath.startsWith('api/')) {
return `https://github.com/company/api-docs/edit/main/${filePath.replace('api/', '')}`
}
// Examples in examples repo
if (filePath.startsWith('examples/')) {
return `https://github.com/company/examples/edit/main/docs/${filePath}`
}
// Main documentation
return `https://github.com/company/docs/edit/main/docs/${filePath}`
},
text: ({ filePath }) => {
if (filePath.startsWith('api/')) return 'Edit API documentation'
if (filePath.startsWith('examples/')) return 'Edit example'
return 'Edit this page'
}
}
}
}