mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-01-29 04:07:37 +01:00
Remove trailing slashes from the website URLs
This commit is contained in:
parent
8b32a3a831
commit
5b93bc42db
@ -10,7 +10,7 @@ export default defineConfig({
|
||||
site: 'https://roadmap.sh',
|
||||
markdown: {
|
||||
shikiConfig: {
|
||||
theme: 'dracula'
|
||||
theme: 'dracula',
|
||||
},
|
||||
rehypePlugins: [
|
||||
[
|
||||
@ -21,6 +21,9 @@ export default defineConfig({
|
||||
],
|
||||
],
|
||||
},
|
||||
build: {
|
||||
format: 'file',
|
||||
},
|
||||
integrations: [
|
||||
tailwind({
|
||||
config: {
|
||||
|
22
sitemap.mjs
22
sitemap.mjs
@ -7,21 +7,21 @@ async function getRoadmapIds() {
|
||||
|
||||
export function shouldIndexPage(page) {
|
||||
return ![
|
||||
'https://roadmap.sh/404/',
|
||||
'https://roadmap.sh/terms/',
|
||||
'https://roadmap.sh/privacy/',
|
||||
'https://roadmap.sh/pdfs/',
|
||||
'https://roadmap.sh/404',
|
||||
'https://roadmap.sh/terms',
|
||||
'https://roadmap.sh/privacy',
|
||||
'https://roadmap.sh/pdfs',
|
||||
].includes(page);
|
||||
}
|
||||
|
||||
export async function serializeSitemap(item) {
|
||||
const highPriorityPages = [
|
||||
'https://roadmap.sh/',
|
||||
'https://roadmap.sh/about/',
|
||||
'https://roadmap.sh/roadmaps/',
|
||||
'https://roadmap.sh/guides/',
|
||||
'https://roadmap.sh/videos/',
|
||||
...(await getRoadmapIds()).map((id) => `https://roadmap.sh/${id}/`),
|
||||
'https://roadmap.sh',
|
||||
'https://roadmap.sh/about',
|
||||
'https://roadmap.sh/roadmaps',
|
||||
'https://roadmap.sh/guides',
|
||||
'https://roadmap.sh/videos',
|
||||
...(await getRoadmapIds()).flatMap((id) => [`https://roadmap.sh/${id}`, `https://roadmap.sh/${id}/topics`]),
|
||||
];
|
||||
|
||||
// Roadmaps and other high priority pages
|
||||
@ -37,7 +37,7 @@ export async function serializeSitemap(item) {
|
||||
}
|
||||
|
||||
// Guide and video pages
|
||||
if (item.url.startsWith('https://roadmap.sh/guides/') || item.url.startsWith('https://roadmap.sh/videos/')) {
|
||||
if (item.url.startsWith('https://roadmap.sh/guides') || item.url.startsWith('https://roadmap.sh/videos')) {
|
||||
return {
|
||||
...item,
|
||||
// @ts-ignore
|
||||
|
@ -10,28 +10,35 @@ const { breadcrumbs, roadmapId } = Astro.props;
|
||||
---
|
||||
|
||||
<div class='py-7 pb-6'>
|
||||
<!-- Desktop breadcrums -->
|
||||
<p class='text-gray-500 container hidden sm:block'>
|
||||
{ breadcrumbs.map((breadcrumb, counter) => {
|
||||
<!-- Desktop breadcrums -->
|
||||
<p class='text-gray-500 container hidden sm:block'>
|
||||
{
|
||||
breadcrumbs.map((breadcrumb, counter) => {
|
||||
const isLast = counter === breadcrumbs.length - 1;
|
||||
|
||||
|
||||
if (!isLast) {
|
||||
return (
|
||||
<>
|
||||
<a class='hover:text-gray-800' href={`${breadcrumb.url}/`}>{ breadcrumb.title }</a>
|
||||
<a class='hover:text-gray-800' href={`${breadcrumb.url}`}>
|
||||
{breadcrumb.title}
|
||||
</a>
|
||||
<span> · </span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return <span class='text-gray-400'>{ breadcrumb.title }</span>
|
||||
})}
|
||||
</p>
|
||||
|
||||
<!-- Mobile breadcrums -->
|
||||
<p class='container block sm:hidden'>
|
||||
<a class='bg-gray-500 py-1.5 px-3 rounded-md text-white text-xs sm:text-sm font-medium hover:bg-gray-600' href={`/${roadmapId}/`}>
|
||||
← Back to Topics List
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
return <span class='text-gray-400'>{breadcrumb.title}</span>;
|
||||
})
|
||||
}
|
||||
</p>
|
||||
|
||||
<!-- Mobile breadcrums -->
|
||||
<p class='container block sm:hidden'>
|
||||
<a
|
||||
class='bg-gray-500 py-1.5 px-3 rounded-md text-white text-xs sm:text-sm font-medium hover:bg-gray-600'
|
||||
href={`/${roadmapId}`}
|
||||
>
|
||||
← Back to Topics List
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
@ -18,7 +18,7 @@ const { heading, guides } = Astro.props;
|
||||
</div>
|
||||
|
||||
<a
|
||||
href='/guides/'
|
||||
href='/guides'
|
||||
class='hidden sm:inline transition-colors py-2 px-3 text-xs font-medium rounded-full bg-gradient-to-r from-slate-600 to-black hover:from-blue-600 hover:to-blue-800 text-white'
|
||||
>
|
||||
View All Guides →
|
||||
@ -26,7 +26,7 @@ const { heading, guides } = Astro.props;
|
||||
|
||||
<div class='block sm:hidden mt-3'>
|
||||
<a
|
||||
href='/guides/'
|
||||
href='/guides'
|
||||
class='text-sm font-regular block p-2 border border-black text-black rounded-md text-center hover:bg-black hover:text-gray-50'
|
||||
>
|
||||
View All Guides →
|
||||
|
@ -18,7 +18,7 @@ const { heading, videos } = Astro.props;
|
||||
</div>
|
||||
|
||||
<a
|
||||
href='/videos/'
|
||||
href='/videos'
|
||||
class='hidden sm:inline transition-colors py-2 px-3 text-xs font-medium rounded-full bg-gradient-to-r from-slate-600 to-black hover:from-blue-600 hover:to-blue-800 text-white'
|
||||
>
|
||||
View All Videos →
|
||||
@ -26,7 +26,7 @@ const { heading, videos } = Astro.props;
|
||||
|
||||
<div class='block sm:hidden mt-3'>
|
||||
<a
|
||||
href='/videos/'
|
||||
href='/videos'
|
||||
class='text-sm font-regular block p-2 border border-black text-black rounded-md text-center hover:bg-black hover:text-gray-50'
|
||||
>
|
||||
View All Videos →
|
||||
|
@ -4,24 +4,22 @@ import Icon from './Icon.astro';
|
||||
|
||||
<div class='py-6 sm:py-16 pb-10 bg-slate-900 text-white'>
|
||||
<div class='container'>
|
||||
<p
|
||||
class='text-gray-400 font-medium flex flex-col sm:flex-row gap-0 sm:gap-4 mb-8 sm:mb-16 justify-center'
|
||||
>
|
||||
<p class='text-gray-400 font-medium flex flex-col sm:flex-row gap-0 sm:gap-4 mb-8 sm:mb-16 justify-center'>
|
||||
<a
|
||||
class='transition-colors px-2 py-1.5 border-b border-b-gray-700 sm:border-b-0 sm:py-0 sm:px-0 hover:text-white'
|
||||
href='/roadmaps/'>Roadmaps</a
|
||||
href='/roadmaps'>Roadmaps</a
|
||||
>
|
||||
<a
|
||||
class='transition-colors px-2 py-1.5 border-b border-b-gray-700 sm:border-b-0 sm:py-0 sm:px-0 hover:text-white'
|
||||
href='/guides/'>Guides</a
|
||||
href='/guides'>Guides</a
|
||||
>
|
||||
<a
|
||||
class='transition-colors px-2 py-1.5 border-b border-b-gray-700 sm:border-b-0 sm:py-0 sm:px-0 hover:text-white'
|
||||
href='/videos/'>Videos</a
|
||||
href='/videos'>Videos</a
|
||||
>
|
||||
<a
|
||||
class='transition-colors px-2 py-1.5 border-b border-b-gray-700 sm:border-b-0 sm:py-0 sm:px-0 hover:text-white'
|
||||
href='/about/'>About</a
|
||||
href='/about'>About</a
|
||||
>
|
||||
<a
|
||||
class='transition-colors px-2 py-1.5 sm:border-b-0 sm:py-0 sm:px-0 hover:text-white'
|
||||
@ -51,18 +49,18 @@ import Icon from './Icon.astro';
|
||||
</a>
|
||||
</p>
|
||||
<p class='text-slate-300/60 my-4'>
|
||||
Community created roadmaps, articles, resources and journeys to help
|
||||
you choose your path and grow in your career.
|
||||
Community created roadmaps, articles, resources and journeys to help you choose your path and grow in your
|
||||
career.
|
||||
</p>
|
||||
<div class='text-gray-400 text-sm'>
|
||||
<p>
|
||||
© roadmap.sh
|
||||
<span class='mx-1.5'>·</span>
|
||||
<a href='/about/' class='hover:text-white'>FAQs</a>
|
||||
<a href='/about' class='hover:text-white'>FAQs</a>
|
||||
<span class='mx-1.5'>·</span>
|
||||
<a href='/terms/' class='hover:text-white'>Terms</a>
|
||||
<a href='/terms' class='hover:text-white'>Terms</a>
|
||||
<span class='mx-1.5'>·</span>
|
||||
<a href='/privacy/' class='hover:text-white'>Privacy</a>
|
||||
<a href='/privacy' class='hover:text-white'>Privacy</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -78,8 +76,8 @@ import Icon from './Icon.astro';
|
||||
/>
|
||||
</a>
|
||||
<p class='text-slate-300/60 my-4'>
|
||||
The leading DevOps resource for Kubernetes, cloud-native computing,
|
||||
and the latest in at-scale development, deployment, and management.
|
||||
The leading DevOps resource for Kubernetes, cloud-native computing, and the latest in at-scale development,
|
||||
deployment, and management.
|
||||
</p>
|
||||
<div class='text-gray-400 text-sm'>
|
||||
<p>
|
||||
|
@ -10,7 +10,7 @@ const frontmatter = roadmap.frontmatter;
|
||||
---
|
||||
|
||||
<a
|
||||
href={`/${roadmap.id}/`}
|
||||
href={`/${roadmap.id}`}
|
||||
class="bg-gradient-to-r from-slate-900 to-amber-900 hover:from-stone-900 hover:to-stone-900 hover:bg-gray-100 flex flex-col p-2.5 sm:p-5 rounded-md sm:rounded-lg border border-gray-200 relative h-full"
|
||||
>
|
||||
<span
|
||||
|
@ -13,7 +13,7 @@ const { frontmatter, id } = guide;
|
||||
class:list={[
|
||||
"block no-underline py-2 group text-md items-center text-gray-600 hover:text-blue-600 flex justify-between border-b",
|
||||
]}
|
||||
href={`/guides/${id}/`}
|
||||
href={`/guides/${id}`}
|
||||
>
|
||||
<span class="group-hover:translate-x-2 transition-transform">
|
||||
{frontmatter.title}
|
||||
|
@ -12,18 +12,18 @@ import Icon from './Icon.astro';
|
||||
<!-- Desktop navigation items -->
|
||||
<ul class='hidden sm:flex space-x-5'>
|
||||
<li>
|
||||
<a href='/roadmaps/' class='text-gray-400 hover:text-white'>Roadmaps</a>
|
||||
<a href='/roadmaps' class='text-gray-400 hover:text-white'>Roadmaps</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='/guides/' class='text-gray-400 hover:text-white'>Guides</a>
|
||||
<a href='/guides' class='text-gray-400 hover:text-white'>Guides</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='/videos/' class='text-gray-400 hover:text-white'>Videos</a>
|
||||
<a href='/videos' class='text-gray-400 hover:text-white'>Videos</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class='py-2 px-4 text-sm font-regular rounded-full bg-gradient-to-r from-blue-500 to-blue-700 hover:from-blue-500 hover:to-blue-600 text-white'
|
||||
href='/signup/'
|
||||
href='/signup'
|
||||
>
|
||||
Subscribe
|
||||
</a>
|
||||
@ -31,19 +31,12 @@ import Icon from './Icon.astro';
|
||||
</ul>
|
||||
|
||||
<!-- Mobile Navigation Button -->
|
||||
<button
|
||||
class='text-gray-400 hover:text-gray-50 block sm:hidden cursor-pointer'
|
||||
aria-label='Menu'
|
||||
show-mobile-nav
|
||||
>
|
||||
<button class='text-gray-400 hover:text-gray-50 block sm:hidden cursor-pointer' aria-label='Menu' show-mobile-nav>
|
||||
<Icon icon='hamburger' />
|
||||
</button>
|
||||
|
||||
<!-- Mobile Navigation Items -->
|
||||
<div
|
||||
class='fixed top-0 bottom-0 left-0 right-0 z-40 bg-slate-900 items-center flex hidden'
|
||||
mobile-nav
|
||||
>
|
||||
<div class='fixed top-0 bottom-0 left-0 right-0 z-40 bg-slate-900 items-center flex hidden' mobile-nav>
|
||||
<button
|
||||
close-mobile-nav
|
||||
class='text-gray-400 hover:text-gray-50 block cursor-pointer absolute top-6 right-6'
|
||||
@ -53,26 +46,16 @@ import Icon from './Icon.astro';
|
||||
</button>
|
||||
<ul class='flex flex-col gap-2 md:gap-3 items-center w-full'>
|
||||
<li>
|
||||
<a href='/roadmaps/' class='text-xl md:text-lg hover:text-blue-300'
|
||||
>Roadmaps</a
|
||||
>
|
||||
<a href='/roadmaps' class='text-xl md:text-lg hover:text-blue-300'>Roadmaps</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='/guides/' class='text-xl md:text-lg hover:text-blue-300'
|
||||
>Guides</a
|
||||
>
|
||||
<a href='/guides' class='text-xl md:text-lg hover:text-blue-300'>Guides</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href='/videos/' class='text-xl md:text-lg hover:text-blue-300'
|
||||
>Videos</a
|
||||
>
|
||||
<a href='/videos' class='text-xl md:text-lg hover:text-blue-300'>Videos</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href='/signup/'
|
||||
class='text-xl md:text-lg text-red-300 hover:text-red-400'
|
||||
>Subscribe</a
|
||||
>
|
||||
<a href='/signup' class='text-xl md:text-lg text-red-300 hover:text-red-400'>Subscribe</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -84,9 +67,7 @@ import Icon from './Icon.astro';
|
||||
document.querySelector('[mobile-nav]')?.classList.remove('hidden');
|
||||
});
|
||||
|
||||
document
|
||||
.querySelector('[close-mobile-nav]')
|
||||
?.addEventListener('click', () => {
|
||||
document.querySelector('[mobile-nav]')?.classList.add('hidden');
|
||||
});
|
||||
document.querySelector('[close-mobile-nav]')?.addEventListener('click', () => {
|
||||
document.querySelector('[mobile-nav]')?.classList.add('hidden');
|
||||
});
|
||||
</script>
|
||||
|
@ -8,10 +8,7 @@ export interface Props {
|
||||
const { roadmapId } = Astro.props;
|
||||
|
||||
const hasTNSBanner = ['frontend', 'backend', 'devops'].includes(roadmapId);
|
||||
const roadmapTitle =
|
||||
roadmapId === 'devops'
|
||||
? 'DevOps'
|
||||
: `${roadmapId.charAt(0).toUpperCase()}${roadmapId.slice(1)}`;
|
||||
const roadmapTitle = roadmapId === 'devops' ? 'DevOps' : `${roadmapId.charAt(0).toUpperCase()}${roadmapId.slice(1)}`;
|
||||
---
|
||||
|
||||
<div
|
||||
@ -54,15 +51,12 @@ const roadmapTitle =
|
||||
]}
|
||||
>
|
||||
<p class='text-sm'>
|
||||
<span
|
||||
class='text-yellow-900 bg-yellow-200 py-0.5 px-1 text-xs rounded-sm font-medium uppercase mr-0.5'
|
||||
>New</span
|
||||
>
|
||||
<span class='text-yellow-900 bg-yellow-200 py-0.5 px-1 text-xs rounded-sm font-medium uppercase mr-0.5'>New</span>
|
||||
Resources are here, try clicking nodes
|
||||
</p>
|
||||
|
||||
<a
|
||||
href={`/${roadmapId}/topics/`}
|
||||
href={`/${roadmapId}/topics`}
|
||||
class='inline-flex items-center justify-center py-1.5 text-sm font-medium rounded-md hover:text-black text-gray-500 px-1'
|
||||
>
|
||||
<Icon icon='search' />
|
||||
@ -71,13 +65,8 @@ const roadmapTitle =
|
||||
</div>
|
||||
|
||||
<!-- Mobile - Roadmap resources alert -->
|
||||
<p
|
||||
class='block sm:hidden text-sm border border-yellow-500 text-yellow-700 rounded-md py-1.5 px-2 bg-white relative'
|
||||
>
|
||||
<p class='block sm:hidden text-sm border border-yellow-500 text-yellow-700 rounded-md py-1.5 px-2 bg-white relative'>
|
||||
Click roadmap items for resources or visit{' '}
|
||||
<a href={`/${roadmapId}/topics/`} class='text-blue-700 underline'>
|
||||
resources list
|
||||
</a>
|
||||
.
|
||||
<a href={`/${roadmapId}/topics`} class='text-blue-700 underline'> resources list</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -10,17 +10,13 @@ const { roadmap, roadmapId } = Astro.props;
|
||||
---
|
||||
|
||||
<a
|
||||
href={`/${roadmapId}/`}
|
||||
class="flex items-center justify-center bg-yellow-100 text-yellow-900 border-b py-2 sm:py-3 text-sm sm:text-md hover:bg-yellow-200"
|
||||
href={`/${roadmapId}`}
|
||||
class='flex items-center justify-center bg-yellow-100 text-yellow-900 border-b py-2 sm:py-3 text-sm sm:text-md hover:bg-yellow-200'
|
||||
>
|
||||
<span class="container">
|
||||
<span class="hidden sm:inline"
|
||||
>Click to visit the interactive version of</span
|
||||
>
|
||||
<span class="inline sm:hidden">Visit complete</span>
|
||||
<span class='container'>
|
||||
<span class='hidden sm:inline'>Click to visit the interactive version of</span>
|
||||
<span class='inline sm:hidden'>Visit complete</span>
|
||||
|
||||
<span class="sm:lowercase ml-0.5 font-medium underline underline-offset-1"
|
||||
>{roadmap.featuredTitle} roadmap</span
|
||||
>
|
||||
<span class='sm:lowercase ml-0.5 font-medium underline underline-offset-1'>{roadmap.featuredTitle} roadmap</span>
|
||||
</span>
|
||||
</a>
|
||||
|
@ -37,7 +37,7 @@ const isRoadmapReady = !isUpcoming;
|
||||
!hasSearch && (
|
||||
<>
|
||||
<a
|
||||
href='/roadmaps/'
|
||||
href='/roadmaps'
|
||||
class='bg-gray-500 py-1.5 px-3 rounded-md text-white text-xs sm:text-sm font-medium hover:bg-gray-600'
|
||||
aria-label='Back to All Roadmaps'
|
||||
>
|
||||
@ -76,7 +76,7 @@ const isRoadmapReady = !isUpcoming;
|
||||
{
|
||||
hasSearch && (
|
||||
<a
|
||||
href={`/${roadmapId}/`}
|
||||
href={`/${roadmapId}`}
|
||||
class='bg-gray-500 py-1.5 px-3 rounded-md text-white text-xs sm:text-sm font-medium hover:bg-gray-600'
|
||||
aria-label='Back to Visual Roadmap'
|
||||
>
|
||||
|
@ -1,21 +1,19 @@
|
||||
---
|
||||
import Icon from "../Icon.astro";
|
||||
import Icon from '../Icon.astro';
|
||||
---
|
||||
|
||||
<script src="./topics.js" />
|
||||
<script src='./topics.js'></script>
|
||||
|
||||
<div class="sm:-mb-[68px] mt-5 sm:mt-6 relative">
|
||||
<div class='sm:-mb-[68px] mt-5 sm:mt-6 relative'>
|
||||
<input
|
||||
autofocus
|
||||
type="text"
|
||||
id="search-topic-input"
|
||||
class="border border-gray-300 text-gray-900 text-sm sm:text-md rounded-md focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 sm:px-3 py-2"
|
||||
placeholder="Search for a topic"
|
||||
type='text'
|
||||
id='search-topic-input'
|
||||
class='border border-gray-300 text-gray-900 text-sm sm:text-md rounded-md focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 sm:px-3 py-2'
|
||||
placeholder='Search for a topic'
|
||||
/>
|
||||
|
||||
<span
|
||||
class="absolute top-1/2 -translate-y-1/2 right-4 flex items-center text-sm text-gray-500"
|
||||
>
|
||||
<Icon icon="search" />
|
||||
<span class='absolute top-1/2 -translate-y-1/2 right-4 flex items-center text-sm text-gray-500'>
|
||||
<Icon icon='search' />
|
||||
</span>
|
||||
</div>
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
import type { VideoFileType } from "../lib/video";
|
||||
import type { VideoFileType } from '../lib/video';
|
||||
|
||||
export interface Props {
|
||||
video: VideoFileType;
|
||||
@ -11,30 +11,30 @@ const { frontmatter, id } = video;
|
||||
|
||||
<a
|
||||
class:list={[
|
||||
"block no-underline py-2 group text-md items-center text-gray-600 hover:text-blue-600 flex justify-between border-b",
|
||||
'block no-underline py-2 group text-md items-center text-gray-600 hover:text-blue-600 flex justify-between border-b',
|
||||
]}
|
||||
href={`/videos/${id}/`}
|
||||
href={`/videos/${id}`}
|
||||
>
|
||||
<span class="group-hover:translate-x-2 transition-transform">
|
||||
<span class='group-hover:translate-x-2 transition-transform'>
|
||||
{frontmatter.title}
|
||||
|
||||
{
|
||||
frontmatter.isNew && (
|
||||
<span class="bg-green-300 text-green-900 text-xs font-medium px-1.5 py-0.5 rounded-sm uppercase ml-1.5">
|
||||
<span class='bg-green-300 text-green-900 text-xs font-medium px-1.5 py-0.5 rounded-sm uppercase ml-1.5'>
|
||||
New
|
||||
<span class="hidden sm:inline">
|
||||
<span class='hidden sm:inline'>
|
||||
·
|
||||
{new Date(frontmatter.date).toLocaleString("default", {
|
||||
month: "long",
|
||||
{new Date(frontmatter.date).toLocaleString('default', {
|
||||
month: 'long',
|
||||
})}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
</span>
|
||||
<span class="capitalize text-gray-500 text-xs hidden sm:block">
|
||||
<span class='capitalize text-gray-500 text-xs hidden sm:block'>
|
||||
{frontmatter.duration}
|
||||
</span>
|
||||
|
||||
<span class="text-gray-400 text-xs block sm:hidden"> »</span>
|
||||
<span class='text-gray-400 text-xs block sm:hidden'> »</span>
|
||||
</a>
|
||||
|
@ -2,17 +2,14 @@
|
||||
import Icon from './Icon.astro';
|
||||
---
|
||||
|
||||
<div
|
||||
class='sticky top-0 border-b border-b-yellow-300 z-20 flex h-[37px]'
|
||||
youtube-banner
|
||||
>
|
||||
<div class='sticky top-0 border-b border-b-yellow-300 z-20 flex h-[37px]' youtube-banner>
|
||||
<a
|
||||
href='https://youtube.com/theroadmap?sub_confirmation=1'
|
||||
target='_blank'
|
||||
class='flex bg-yellow-200 text-center flex-1 items-center justify-center text-sm hover:bg-yellow-300 outline-0'
|
||||
>
|
||||
<Icon icon='youtube' class='mr-2' /> We now have a YouTube Channel. <span
|
||||
class='hidden sm:inline'>Subscribe for the video content.</span
|
||||
<Icon icon='youtube' class='mr-2' /> We now have a YouTube Channel. <span class='hidden sm:inline'
|
||||
>Subscribe for the video content.</span
|
||||
>
|
||||
</a>
|
||||
<button
|
||||
@ -25,9 +22,7 @@ import Icon from './Icon.astro';
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document
|
||||
.querySelector('[close-youtube-banner]')
|
||||
?.addEventListener('click', () => {
|
||||
document.querySelector('[youtube-banner]').remove();
|
||||
});
|
||||
document.querySelector('[close-youtube-banner]')?.addEventListener('click', () => {
|
||||
document.querySelector('[youtube-banner]')?.remove();
|
||||
});
|
||||
</script>
|
||||
|
@ -3,7 +3,7 @@ import Icon from '../components/Icon.astro';
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
---
|
||||
|
||||
<BaseLayout title='Page not found' permalink={'/404/'}>
|
||||
<BaseLayout title='Page not found' permalink={'/404'}>
|
||||
<div class='bg-gray-100'>
|
||||
<div
|
||||
class='py-10 md:py-32 container flex flex-col md:flex-row items-center justify-center gap-7 '
|
||||
@ -19,7 +19,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
Sorry, we couldn't find the page you are looking for.
|
||||
</p>
|
||||
<p>
|
||||
<a class="underline text-blue-700" href='/'>Homepage</a> · <a href='/roadmaps/' class="underline text-blue-700">Roadmaps</a> · <a href='/videos/' class="underline text-blue-700">Videos</a>
|
||||
<a class="underline text-blue-700" href='/'>Homepage</a> · <a href='/roadmaps' class="underline text-blue-700">Roadmaps</a> · <a href='/videos' class="underline text-blue-700">Videos</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -21,7 +21,7 @@ const { file, breadcrumbs, roadmapId, roadmap, heading } = Astro.props as TopicF
|
||||
title={`${heading} - roadmap.sh`}
|
||||
description={`Free resources to learn ${heading} in ${roadmap.featuredTitle}. Everything you need to know about ${heading} and how it realtes to ${roadmap.featuredTitle}.`}
|
||||
noIndex={true}
|
||||
permalink={`/${topicId}/`}
|
||||
permalink={`/${topicId}`}
|
||||
>
|
||||
<RoadmapBanner roadmapId={roadmapId} roadmap={roadmap} />
|
||||
<div class='bg-gray-50'>
|
||||
|
@ -48,7 +48,7 @@ if (roadmapFAQs.length) {
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
permalink={`/${roadmapId}/`}
|
||||
permalink={`/${roadmapId}`}
|
||||
title={roadmapData?.seo?.title}
|
||||
description={roadmapData.seo.description}
|
||||
keywords={roadmapData.seo.keywords}
|
||||
|
@ -26,7 +26,7 @@ const roadmapData = roadmapFile.frontmatter as RoadmapFrontmatter;
|
||||
title={`${roadmapData.title} Topics`}
|
||||
description={roadmapData.seo.description}
|
||||
keywords={roadmapData.seo.keywords}
|
||||
permalink={`/${roadmapId}/topics/`}
|
||||
permalink={`/${roadmapId}/topics`}
|
||||
>
|
||||
<RoadmapHeader
|
||||
description={roadmapData.description}
|
||||
@ -59,7 +59,7 @@ const roadmapData = roadmapFile.frontmatter as RoadmapFrontmatter;
|
||||
'bg-gray-100 hover:bg-gray-300': totalParentCount === 3,
|
||||
},
|
||||
]}
|
||||
href={`${topic.url}/`}
|
||||
href={`${topic.url}`}
|
||||
>
|
||||
{topic.heading}
|
||||
</a>
|
||||
|
@ -2,7 +2,7 @@
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
---
|
||||
|
||||
<BaseLayout title='About roadmap.sh' permalink={'/about/'}>
|
||||
<BaseLayout title='About roadmap.sh' permalink={'/about'}>
|
||||
<div class='bg-white border-b pt-7 pb-7 sm:pt-12 sm:pb-10'>
|
||||
<div class='container'>
|
||||
<div class='flex items-center'>
|
||||
|
@ -24,7 +24,7 @@ const { frontmatter: guideData } = guide;
|
||||
<BaseLayout
|
||||
title={guideData.seo.title}
|
||||
description={guideData.seo.description}
|
||||
permalink={`/guides/${guideId}/`}
|
||||
permalink={`/guides/${guideId}`}
|
||||
canonicalUrl={guideData.canonicalUrl}
|
||||
>
|
||||
<GuideHeader guide={guide} />
|
||||
|
@ -10,12 +10,9 @@ const guides = await getAllGuides();
|
||||
<BaseLayout
|
||||
title='Guides - roadmap.sh'
|
||||
description={'Detailed guides on Software Engineering Topics'}
|
||||
permalink={`/guides/`}
|
||||
permalink={`/guides`}
|
||||
>
|
||||
<SimplePageHeader
|
||||
title='Guides'
|
||||
description='Succinct graphical explanations to engineering topics.'
|
||||
/>
|
||||
<SimplePageHeader title='Guides' description='Succinct graphical explanations to engineering topics.' />
|
||||
|
||||
<div class='pb-20 pt-2 bg-gray-50'>
|
||||
<div class='container'>
|
||||
|
@ -9,6 +9,7 @@ import { getAllVideos } from '../lib/video';
|
||||
|
||||
const roleRoadmaps = await getRoadmapsByTag('role-roadmap');
|
||||
const skillRoadmaps = await getRoadmapsByTag('skill-roadmap');
|
||||
|
||||
const guides = await getAllGuides();
|
||||
const videos = await getAllVideos();
|
||||
---
|
||||
@ -42,7 +43,7 @@ const videos = await getAllVideos();
|
||||
heading='Role based Roadmaps'
|
||||
featuredItems={roleRoadmaps.map((roadmapItem) => ({
|
||||
text: roadmapItem.frontmatter.featuredTitle,
|
||||
url: `/${roadmapItem.id}/`,
|
||||
url: `/${roadmapItem.id}`,
|
||||
isNew: roadmapItem.frontmatter.isNew,
|
||||
isUpcoming: roadmapItem.frontmatter.isUpcoming,
|
||||
}))}
|
||||
@ -52,7 +53,7 @@ const videos = await getAllVideos();
|
||||
heading='Skill based Roadmaps'
|
||||
featuredItems={skillRoadmaps.map((roadmapItem) => ({
|
||||
text: roadmapItem.frontmatter.featuredTitle === 'Go' ? 'Go Roadmap' : roadmapItem.frontmatter.featuredTitle,
|
||||
url: `/${roadmapItem.id}/`,
|
||||
url: `/${roadmapItem.id}`,
|
||||
isNew: roadmapItem.frontmatter.isNew,
|
||||
isUpcoming: roadmapItem.frontmatter.isUpcoming,
|
||||
}))}
|
||||
|
@ -6,7 +6,7 @@ noIndex: true
|
||||
|
||||
# Privacy Policy
|
||||
|
||||
By using or accessing the Services in any manner, you acknowledge that you accept the practices and policies outlined in this Privacy Policy, and you hereby consent that we will collect, use, and share your information in the following ways. Remember that your use of roadmap.sh’s Services is at all times subject to the [Terms of Use](/terms/), which incorporates this Privacy Policy. Any terms we use in this Policy without defining them have the definitions given to them in the Terms of Use.
|
||||
By using or accessing the Services in any manner, you acknowledge that you accept the practices and policies outlined in this Privacy Policy, and you hereby consent that we will collect, use, and share your information in the following ways. Remember that your use of roadmap.sh’s Services is at all times subject to the [Terms of Use](/terms), which incorporates this Privacy Policy. Any terms we use in this Policy without defining them have the definitions given to them in the Terms of Use.
|
||||
|
||||
## What does this Privacy Policy cover?
|
||||
|
||||
|
@ -11,7 +11,7 @@ const skillRoadmaps = await getRoadmapsByTag('skill-roadmap');
|
||||
<BaseLayout
|
||||
title='Developer Roadmaps'
|
||||
description={'Step by step guides and paths to learn different tools or technologies'}
|
||||
permalink={'/roadmaps/'}
|
||||
permalink={'/roadmaps'}
|
||||
>
|
||||
<SimplePageHeader
|
||||
title='Developer Roadmaps'
|
||||
|
@ -7,7 +7,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
<BaseLayout
|
||||
title='Signup - roadmap.sh'
|
||||
description='Register yourself to receive occasional emails about new roadmaps, updates, guides and videos'
|
||||
permalink={'/signup/'}
|
||||
permalink={'/signup'}
|
||||
noIndex={true}
|
||||
>
|
||||
<div class='container'>
|
||||
|
@ -23,7 +23,7 @@ const { video } = Astro.props;
|
||||
<BaseLayout
|
||||
title={video.frontmatter.title}
|
||||
description={video.frontmatter.description}
|
||||
permalink={`/videos/${videoId}/`}
|
||||
permalink={`/videos/${videoId}`}
|
||||
>
|
||||
<VideoHeader video={video} />
|
||||
|
||||
|
@ -10,12 +10,9 @@ const videos = await getAllVideos();
|
||||
<BaseLayout
|
||||
title='Illustrated Videos - roadmap.sh'
|
||||
description={'Graphical video demonstrations on software engineering topics.'}
|
||||
permalink={`/videos/`}
|
||||
permalink={`/videos`}
|
||||
>
|
||||
<SimplePageHeader
|
||||
title='Videos'
|
||||
description='Graphical video demonstrations on software engineering topics.'
|
||||
/>
|
||||
<SimplePageHeader title='Videos' description='Graphical video demonstrations on software engineering topics.' />
|
||||
|
||||
<div class='pb-20 pt-2 bg-gray-50'>
|
||||
<div class='container'>
|
||||
|
Loading…
x
Reference in New Issue
Block a user