Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions data/resources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[{"title":"JavaScript schema library from the Future 🧬","description":"ReScript Schema - The fastest parser in the entire JavaScript ecosystem with a focus on small bundle... Tagged with schema, typescript, rescript, opensource.","image":"https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn102ksd9w1xo5ysgxbur.png","url":"https://dev.to/dzakh/javascript-schema-library-from-the-future-5420"},{"title":"ReScript: A Better Typed JavaScript? (with Gabriel Nordeborn)","description":"ReScript is a strongly-typed programming language that compiles to JavaScript, and that puts it squarely in competition with TypeScript. So why would a JavaS...","image":"https://i.ytimg.com/vi/yKl2fSdnw7w/maxresdefault.jpg","url":"https://www.youtube.com/watch?v=yKl2fSdnw7w"},{"title":"GitHub - rescript-lang/awesome-rescript: A collection of materials about the ReScript programming language and toolchain.","description":"A collection of materials about the ReScript programming language and toolchain. - rescript-lang/awesome-rescript","image":"https://repository-images.githubusercontent.com/395642331/9d6aaef3-c81c-4156-8f65-45c3dbd011ac","url":"https://github.com/rescript-lang/awesome-rescript"},{"title":"An early look at @rescript/webapi","description":"Here's an early look at the new ReScript Web API bindings I've been working on.For more information, visit https://rescript-lang.github.io/experimental-rescr...","image":"https://i.ytimg.com/vi/MC-dbM-GEuw/maxresdefault.jpg","url":"https://www.youtube.com/watch?v=MC-dbM-GEuw"},{"title":"ReScript has come a long way, maybe it's time to switch from TypeScript?","description":"ReScript, the \"Fast, Simple, Fully Typed JavaScript from the Future\", has been around for awhile now.... Tagged with rescript, javascript, typescript, webdev.","image":"https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5jrqcbteob11bc7nvwz9.jpg","url":"https://dev.to/jderochervlk/rescript-has-come-a-long-way-maybe-its-time-to-switch-from-typescript-29he"},{"title":"Create a Snake Game in ReScript","description":"Let's create a simple snake game in ReScript without using any framework.Full code here https://github.com/Exegetech/snake-rescript00:00 Getting started03:20...","image":"https://i.ytimg.com/vi/f0gDMjuaCZo/maxresdefault.jpg","url":"https://www.youtube.com/watch?v=f0gDMjuaCZo"},{"title":"ReScript and EdgeDB | Gel Blog","description":"Learn how together ReScript and EdgeDB achieve full type safety with less busy work. This post shows you the benefits and how you can get started with this pairing today!","image":"https://www.geldata.com/_images/_blog/ab9848d310c94bb25e21f219ee74b7f24ca16baa.jpg","url":"https://www.geldata.com/blog/rescript-and-edgedb"},{"title":"Building and consuming REST API in ReScript with rescript-rest and Fastify","description":"In the video, I show how you can use my ReScript Rest library to create an HTTP server with Fastify, generate OpenAPI for it, and then consume it on the clie...","image":"https://i.ytimg.com/vi/37FY6a-zY20/maxresdefault.jpg?sqp=-oaymwEmCIAKENAF8quKqQMa8AEB-AH-CYAC0AWKAgwIABABGEsgXShlMA8=&rs=AOn4CLBrz-ZJf8pcr_1_YZCfiMUwFKqj6A","url":"https://www.youtube.com/watch?v=37FY6a-zY20"},{"title":"When and Where to use ReScript? The ReScript happy path","description":"Are you ever hesitant about adopting ReScript, or have you tried it and been frustrated? I will give you a realistic guide for adopting ReScript in the project. (Hint: Review your project architecture first). Tagged with rescript, typescript, architecture.","image":"https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fool4835vdaqw8vueb9b5.png","url":"https://dev.to/cometkim/when-and-where-to-use-rescript-the-rescript-happy-path-47ni"},{"title":"From TypeScript To ReScript | Serhii Potapov (greyblake)","description":"A blog about software development.","image":"https://www.greyblake.com/greyblake.jpeg","url":"https://www.greyblake.com/blog/from-typescript-to-rescript/"},{"title":"Getting rid of your dead code in ReScript","description":"Exploring ReScript's tools for eliminating dead code, keeping your repository clean and without... Tagged with rescript.","image":"https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F12lsasc06v1a355i6rfk.jpeg","url":"https://dev.to/zth/getting-rid-of-your-dead-code-in-rescript-3mba"},{"title":"Rescript React Error boundary usage","description":"Hi I was trying to capture the react errors. I had to write the bindings for the ErrorBoundary and... Tagged with rescript, react.","image":"https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3otvb2z646ytpt1hl2rv.jpg","url":"https://dev.to/srikanthkyatham/rescript-react-error-boundary-usage-3b05"},{"title":"Full-stack ReScript. Architecture Overview","description":"Can ReScript be used to create a full-featured back-end? In this article, I’d try to prove it can and does it with success.\n","image":"","url":"https://fullsteak.dev/posts/fullstack-rescript-architecture-overview"},{"title":"ReScript for React Development","description":"Looking for ReScript for React Development information? In this article, I highlight the development & business advantages of ReScript.","image":"https://scalac.io/wp-content/uploads/2021/08/ReScript-for-React-Development-FB.png","url":"https://scalac.io/blog/rescript-for-react-development/"},{"title":"Rewriting a Project in ReScript","description":"My experience reimplementing a small project in ReScript","image":"","url":"https://yangdanny97.github.io/blog/2021/07/09/Migrating-to-Rescript"},{"title":"Responsive Images and Cumulative Layout Shift","description":"Solving cumulative layout shift issue caused by responsive images in layouts.","image":"https://d20bjcorj7xdk.cloudfront.net/eyJidWNrZXQiOiJpbWFnZXMuYWxleGZlZG9zZWV2LmNvbSIsImtleSI6Im1ldGEtYmxvZy5wbmciLCJlZGl0cyI6eyJyZXNpemUiOnsid2lkdGgiOjEyMDAsImhlaWdodCI6NjMwLCJmaXQiOiJjb3ZlciJ9LCJqcGVnIjp7InF1YWxpdHkiOjkwfX19?signature=d8e6c0ac1ff03d0f5ee04d128b96a7701b998952a38ba96e9a16e4414cd05ed0&version=58cfd6f8abdefeca2195a6a1f1108596","url":"https://alexfedoseev.com/blog/post/responsive-images-and-cumulative-layout-shift"},{"title":"ReScript records, NextJS, undefined and getStaticProps","description":"NextJS, a pretty solid framework for building React based websites and web-applications, offers a nic... Tagged with rescript, javascript, nextjs.","image":"https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3otvb2z646ytpt1hl2rv.jpg","url":"https://dev.to/ryyppy/rescript-records-nextjs-undefined-and-getstaticprops-4890"}]

3 changes: 2 additions & 1 deletion data/sidebar_community.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"Resources": [
"overview",
"content",
"roadmap",
"code-of-conduct",
"translations"
]
}
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
"test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs",
"reanalyze": "reanalyze -all-cmt .",
"update-index": "npm run generate-llms && node scripts/extract-indices.mjs && node scripts/extract-tocs.mjs && node scripts/extract-syntax.mjs && node scripts/generate_feed.mjs > public/blog/feed.xml",
"generate-llms": "node scripts/generate_llms.mjs"
"generate-llms": "node scripts/generate_llms.mjs",
"generate-resources": "node scripts/generate_resources.mjs"
},
"devDependencies": {
"@mdx-js/react": "^2.3.0",
Expand All @@ -78,4 +79,4 @@
"simple-functional-loader": "^1.2.1",
"tailwindcss": "^3.3.3"
}
}
}
10 changes: 10 additions & 0 deletions pages/community/content.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: "Content"
description: "Community Content"
canonical: "/community/content"
---


import CommunityContent from 'src/CommunityContent.mjs';

<CommunityContent />
10 changes: 1 addition & 9 deletions pages/community/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: "Community Resources Overview"
canonical: "/community/overview"
---

# Community
# Community Overview

## Official Channels

Expand All @@ -14,19 +14,11 @@ canonical: "/community/overview"
- [Forum](https://forum.rescript-lang.org)
- [ReScript GitHub Org](https://github.com/rescript-lang/)
- [ReScript YouTube Channel](https://www.youtube.com/@rescriptlang)
- [ReScript Online Meetup on Guild](https://guild.host/rescript-online-meetup)
- [ReScript Online Meetup YouTube Channel](https://www.youtube.com/@ReScriptOnlineMeetup)

News are broadcasted on this site's blog, on Bluesky and X. Some extra, less important news are also posted on the forum's [Announcements category](https://forum.rescript-lang.org/c/announcements/).

**We don't use any other channel to communicate officially**. Any announcement made by users on Reddit, Discord, Medium and others don't necessarily represent our intent.

## Articles

- [Getting rid of your dead code in ReScript](https://dev.to/zth/getting-rid-of-your-dead-code-in-rescript-3mba)
- [Speeding up ReScript compilation using interface files](https://dev.to/zth/speeding-up-rescript-compilation-using-interface-files-4fgn)
- Articles in [awesome-rescript](https://github.com/fhammerschmidt/awesome-rescript#readme)

## Questions

Your questions can go on:
Expand Down
6 changes: 5 additions & 1 deletion pages/docs/manual/v11.0.0/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ Our focus is a solid JS story right now. In the future, if there’s strong dema

**What’s the current state of ReScript?**

Currently, we're actively working on the editor support.
We're working on the v12.0 release (see [v12 milestone](https://github.com/rescript-lang/rescript/milestone/16)).

- Move the [Rescript Core](https://github.com/rescript-lang/rescript-core) standard library into the compiler / remove the OCaml standard library
- A new build system tailored to ReScript's needs ([rewatch](https://github.com/teamwalnut/rewatch)) for better monorepo support and even faster compilation speed
- Make it easier to create libraries for consumption from TypeScript with GenType

**When will we get the `async/await` keywords?**

Expand Down
6 changes: 5 additions & 1 deletion pages/docs/manual/v12.0.0/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ Our focus is a solid JS story right now. In the future, if there’s strong dema

**What’s the current state of ReScript?**

Currently, we're actively working on the editor support.
We're working on the v12.0 release (see [v12 milestone](https://github.com/rescript-lang/rescript/milestone/16)).

- Move the [Rescript Core](https://github.com/rescript-lang/rescript-core) standard library into the compiler / remove the OCaml standard library
- A new build system tailored to ReScript's needs ([rewatch](https://github.com/teamwalnut/rewatch)) for better monorepo support and even faster compilation speed
- Make it easier to create libraries for consumption from TypeScript with GenType

**When will we get the `async/await` keywords?**

Expand Down
50 changes: 50 additions & 0 deletions scripts/generate_resources.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/** This is the list of community content we want to generate. */
/** If you have content you would like to add, please open up a PR adding the link to this list and then run `npm run generate_resources` */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment needs an update to kebap-case as well now

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

let urls = [
// 2025
"https://dev.to/dzakh/javascript-schema-library-from-the-future-5420",
"https://www.youtube.com/watch?v=yKl2fSdnw7w",
"https://github.com/rescript-lang/awesome-rescript", // regardless of age this seems like it should always be near the top
// 2024
"https://www.youtube.com/watch?v=MC-dbM-GEuw",
"https://dev.to/jderochervlk/rescript-has-come-a-long-way-maybe-its-time-to-switch-from-typescript-29he",
"https://www.youtube.com/watch?v=f0gDMjuaCZo",
"https://www.geldata.com/blog/rescript-and-edgedb",
"https://www.youtube.com/watch?v=37FY6a-zY20",
// 2023
"https://dev.to/cometkim/when-and-where-to-use-rescript-the-rescript-happy-path-47ni",
// 2022
"https://www.greyblake.com/blog/from-typescript-to-rescript/",
"https://dev.to/zth/getting-rid-of-your-dead-code-in-rescript-3mba",
"https://www.youtube.com/watch?v=KDL-kRgilkQ",
"https://dev.to/srikanthkyatham/rescript-react-error-boundary-usage-3b05",
// "https://www.daggala.com/belt_vs_js_array_in_rescript/" I think we should exclude this one since it's related to API we are deprecating
// 2021
"https://fullsteak.dev/posts/fullstack-rescript-architecture-overview",
"https://scalac.io/blog/rescript-for-react-development/",
"https://yangdanny97.github.io/blog/2021/07/09/Migrating-to-Rescript",
"https://alexfedoseev.com/blog/post/responsive-images-and-cumulative-layout-shift",
"https://dev.to/ryyppy/rescript-records-nextjs-undefined-and-getstaticprops-4890",
]

let generate = async () => {
let filePath = "data/resources.json"
let metaData = await MetaTagsApi.getMetaTags(urls)

let fileContent = `${metaData
->Array.map(i =>
{
"title": `${i.title->Option.getOr("")}`,
"description": `${i.description->Option.getOr("")}`,
"image": `${i.image->Option.getOr("")}`,
"url": `${i.url}`,
}
)
->JSON.stringifyAny
->Option.getOr("[]")}
`

Node.Fs.writeFileSync(filePath, fileContent)
}

await generate()
68 changes: 68 additions & 0 deletions src/CommunityContent.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
type link = {
url: string,
title: string,
description: string,
image: string,
}

@module("../data/resources.json")
external resources: array<link> = "default"

let simplifyUrl = url =>
url
->String.replace("https://", "")
->String.replace("http://", "")
->String.split("/")
->Array.at(0)

module LinkCard = {
@react.component
let make = (~link) => {
<div className="rounded-lg hover:text-fire overflow-hidden bg-gray-10">
<a href=link.url className="flex flex-col h-full">
<img className="object-cover w-full md:h-40 max-h-[345px]" src=link.image alt="" />
<div className="p-2 grow">
<h3 className="font-semibold text-16 grow-0 mb-2"> {React.string(link.title)} </h3>
<p className="mb-2 text-14 grow text-gray-80"> {React.string(link.description)} </p>
</div>
<p className="text-14 p-2 grow-0 text-gray-70">
{React.string(link.url->simplifyUrl->Option.getOr(""))}
</p>
</a>
</div>
}
}

module LinkCards = {
@react.component
let make = () => {
<div className="grid md:grid-cols-2 gap-6">
{resources
->Array.map(link =>
switch link.image {
| "" => {...link, image: "/static/Art-3-rescript-launch.jpg"}
| _ => link
}
)
->Array.map(link => <LinkCard link key=link.title />)
->React.array}
</div>
}
}

@react.component
let make = () => {
<div>
<h1 className="hl-1 mb-6"> {"Community Content"->React.string} </h1>
<p className="md-p md:leading-5 tracking-[-0.015em] text-gray-80 md:text-16 mb-16">
{React.string(
"These articles, videos, and resources are created by the amazing ReScript community.",
)}
<br />
{React.string("If you have a resource you'd like to share, please feel free to submit a PR!")}
</p>
<LinkCards />
</div>
}

let default = make
5 changes: 5 additions & 0 deletions src/bindings/Jsdom.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type window = {document: Dom.document}
type t = {window: window}

@module("jsdom") @new
external make: string => t = "JSDOM"
6 changes: 6 additions & 0 deletions src/bindings/Webapi.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ module Document = {
@val external document: Dom.element = "document"
@scope("document") @val external createElement: string => Dom.element = "createElement"
@scope("document") @val external createTextNode: string => Dom.element = "createTextNode"
@send
external querySelector: (Dom.document, string) => Nullable.t<Dom.element> = "querySelector"
@send
external querySelectorAll: (Dom.document, string) => Js.Array2.array_like<Dom.element> =
"querySelectorAll"
}

module ClassList = {
Expand All @@ -17,6 +22,7 @@ module Element = {
@get external classList: Dom.element => ClassList.t = "classList"
@send external getBoundingClientRect: Dom.element => {..} = "getBoundingClientRect"
@send external addEventListener: (Dom.element, string, unit => unit) => unit = "addEventListener"
@send external getAttribute: (Dom.element, string) => Nullable.t<string> = "getAttribute"

@send
external getElementById: (Dom.element, string) => Nullable.t<Dom.element> = "getElementById"
Expand Down
93 changes: 93 additions & 0 deletions src/common/MetaTagsApi.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
type t = {
title: option<string>,
description: option<string>,
image: option<string>,
}

/**
This function uses JSDOM to fetch a webpage and extract the meta tags from it.
JSDOM is required since this runs on Node.
*/
let extractMetaTags = async (url: string) => {
open Webapi
try {
let response = await Fetch.fetch(url)

let html = await response->Fetch.Response.text
let dom = Jsdom.make(html)
let document = dom.window.document

let metaTags =
document
->Document.querySelectorAll("meta")
->Array.fromArrayLike
->Array.reduce(Dict.fromArray([]), (tags, meta) => {
let name = meta->Element.getAttribute("name")->Nullable.toOption
let property = meta->Element.getAttribute("property")->Nullable.toOption
let itemprop = meta->Element.getAttribute("itemprop")->Nullable.toOption

let name = switch (name, property, itemprop) {
| (Some(name), _, _) => Some(name)
| (_, Some(property), _) => Some(property)
| (_, _, Some(itemprop)) => Some(itemprop)
| _ => None
}

let content = meta->Element.getAttribute("content")->Nullable.toOption

switch (name, content) {
| (Some(name), Some(content)) => tags->Dict.set(name, content)
| _ => ()
}

tags
})

let title = metaTags->Dict.get("og:title")
let description = metaTags->Dict.get("og:description")
let image = metaTags->Dict.get("og:image")

Some({
title,
description,
image,
})
} catch {
| _ => {
Console.error(`Error fetching Open Graph details for ${url}`)
None
}
}
}

type tags = {
...t,
url: string,
}

/*
Pass an array of URLs and get back an array of meta tags for each URL.
*/
let getMetaTags = async (urls: array<string>) => {
let metaTags: array<tags> = []
for i in 0 to Array.length(urls) - 1 {
let url = urls[i]
switch url {
| Some(url) => {
let tags = await extractMetaTags(url)
switch tags {
| Some(tags) =>
metaTags->Array.push({
title: tags.title,
description: tags.description,
image: tags.image,
url,
})
| None => ()
}
}
| None => ()
}
}
metaTags
}
8 changes: 7 additions & 1 deletion src/components/Button.res
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ type size = Small | Large
/* type theme = Light | Dark */

@react.component
let make = (~kind: kind=PrimaryRed, ~size: size=Large, ~children) => {
let make = (
~kind: kind=PrimaryRed,
~size: size=Large,
~children,
~onClick: option<JsxEventU.Mouse.t => unit>=?,
) => {
let bgColor = switch kind {
| PrimaryRed => "bg-fire hover:bg-fire-70 text-white"
| PrimaryBlue => "bg-sky hover:bg-sky-70 text-white"
Expand All @@ -16,6 +21,7 @@ let make = (~kind: kind=PrimaryRed, ~size: size=Large, ~children) => {
}

<button
?onClick
role="button"
className={`select-none hover:cursor-pointer transition-colors duration-200 body-button focus:outline-none ${bgColor} ${padding}`}>
children
Expand Down
7 changes: 6 additions & 1 deletion src/components/Button.resi
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ type kind = PrimaryRed | PrimaryBlue | SecondaryRed
type size = Small | Large

@react.component
let make: (~kind: kind=?, ~size: size=?, ~children: React.element) => React.element
let make: (
~kind: kind=?,
~size: size=?,
~children: React.element,
~onClick: JsxEventU.Mouse.t => unit=?,
) => React.element